summaryrefslogtreecommitdiff
path: root/libc/misc
diff options
context:
space:
mode:
Diffstat (limited to 'libc/misc')
-rw-r--r--libc/misc/Makefile.in3
-rw-r--r--libc/misc/assert/Makefile.in16
-rw-r--r--libc/misc/assert/__assert.c15
-rw-r--r--libc/misc/ctype/Makefile.in34
-rw-r--r--libc/misc/ctype/ctype.c90
-rw-r--r--libc/misc/dirent/Makefile.in24
-rw-r--r--libc/misc/dirent/alphasort.c11
-rw-r--r--libc/misc/dirent/alphasort64.c13
-rw-r--r--libc/misc/dirent/closedir.c5
-rw-r--r--libc/misc/dirent/dirfd.c1
-rw-r--r--libc/misc/dirent/dirstream.h21
-rw-r--r--libc/misc/dirent/opendir.c98
-rw-r--r--libc/misc/dirent/readdir.c29
-rw-r--r--libc/misc/dirent/readdir64.c53
-rw-r--r--libc/misc/dirent/readdir64_r.c64
-rw-r--r--libc/misc/dirent/readdir_r.c29
-rw-r--r--libc/misc/dirent/rewinddir.c1
-rw-r--r--libc/misc/dirent/scandir.c59
-rw-r--r--libc/misc/dirent/scandir64.c111
-rw-r--r--libc/misc/dirent/seekdir.c1
-rw-r--r--libc/misc/dirent/versionsort.c17
-rw-r--r--libc/misc/dirent/versionsort64.c18
-rw-r--r--libc/misc/elf/Makefile12
-rw-r--r--libc/misc/elf/Makefile.in22
-rw-r--r--libc/misc/elf/dl-core.c20
-rw-r--r--libc/misc/elf/dl-iterate-phdr.c81
-rw-r--r--libc/misc/elf/dl-support.c75
-rw-r--r--libc/misc/error/Makefile.in24
-rw-r--r--libc/misc/error/err.c44
-rw-r--r--libc/misc/error/error.c24
-rw-r--r--libc/misc/file/Makefile.in20
-rw-r--r--libc/misc/file/isfdtype.c40
-rw-r--r--libc/misc/file/issetugid.c10
-rw-r--r--libc/misc/file/lockf.c12
-rw-r--r--libc/misc/file/lockf64.c9
-rw-r--r--libc/misc/fnmatch/Makefile.in20
-rw-r--r--libc/misc/fnmatch/fnmatch.c62
-rw-r--r--libc/misc/fnmatch/fnmatch_loop.c9
-rw-r--r--libc/misc/fnmatch/fnmatch_old.c7
-rw-r--r--libc/misc/fts/Makefile14
-rw-r--r--libc/misc/fts/Makefile.in23
-rw-r--r--libc/misc/fts/fts.c1114
-rw-r--r--libc/misc/ftw/Makefile.in22
-rw-r--r--libc/misc/ftw/ftw.c48
-rw-r--r--libc/misc/ftw/ftw64.c5
-rw-r--r--libc/misc/glob/Makefile.in28
-rw-r--r--libc/misc/glob/glob-susv3.c27
-rw-r--r--libc/misc/glob/glob.c31
-rw-r--r--libc/misc/gnu/Makefile.in17
-rw-r--r--libc/misc/gnu/obprintf.c29
-rw-r--r--libc/misc/gnu/obstack.c413
-rw-r--r--libc/misc/internals/Makefile.in20
-rw-r--r--libc/misc/internals/__errno_location.c15
-rw-r--r--libc/misc/internals/__h_errno_location.c12
-rw-r--r--libc/misc/internals/__uClibc_main.c330
-rw-r--r--libc/misc/internals/errno.c23
-rw-r--r--libc/misc/internals/h_errno.c14
-rw-r--r--libc/misc/internals/internal_errno.h18
-rw-r--r--libc/misc/internals/parse_config.c278
-rw-r--r--libc/misc/internals/tempname.c58
-rw-r--r--libc/misc/internals/tempname.h4
-rw-r--r--libc/misc/locale/Makefile.in25
-rw-r--r--libc/misc/locale/locale.c177
-rw-r--r--libc/misc/mntent/Makefile.in16
-rw-r--r--libc/misc/mntent/mntent.c17
-rw-r--r--libc/misc/pthread/Makefile.in13
-rw-r--r--libc/misc/pthread/tsd.c18
-rw-r--r--libc/misc/pthread/unlock.c27
-rw-r--r--libc/misc/pthread/weaks.c44
-rw-r--r--libc/misc/regex/Makefile.in21
-rw-r--r--libc/misc/regex/_regex.h45
-rw-r--r--libc/misc/regex/regcomp.c298
-rw-r--r--libc/misc/regex/regex.c143
-rw-r--r--libc/misc/regex/regex_internal.c70
-rw-r--r--libc/misc/regex/regex_internal.h127
-rw-r--r--libc/misc/regex/regex_old.c251
-rw-r--r--libc/misc/regex/regexec.c217
-rw-r--r--libc/misc/search/Makefile.in24
-rw-r--r--libc/misc/search/_hsearch_r.c20
-rw-r--r--libc/misc/search/_lsearch.c4
-rw-r--r--libc/misc/search/_tsearch.c18
-rw-r--r--libc/misc/search/hsearch.c8
-rw-r--r--libc/misc/search/insremque.c23
-rw-r--r--libc/misc/statfs/Makefile.in25
-rw-r--r--libc/misc/statfs/fstatfs64.c28
-rw-r--r--libc/misc/statfs/fstatvfs.c15
-rw-r--r--libc/misc/statfs/fstatvfs64.c17
-rw-r--r--libc/misc/statfs/internal_statvfs.c125
-rw-r--r--libc/misc/statfs/statfs64.c27
-rw-r--r--libc/misc/statfs/statvfs.c14
-rw-r--r--libc/misc/statfs/statvfs64.c17
-rw-r--r--libc/misc/syslog/Makefile.in16
-rw-r--r--libc/misc/syslog/syslog.c185
-rw-r--r--libc/misc/sysvipc/Makefile.in22
-rw-r--r--libc/misc/sysvipc/__syscall_ipc.c2
-rw-r--r--libc/misc/sysvipc/ftok.c14
-rw-r--r--libc/misc/sysvipc/ipc.h10
-rw-r--r--libc/misc/sysvipc/msgq.c55
-rw-r--r--libc/misc/sysvipc/sem.c19
-rw-r--r--libc/misc/sysvipc/shm.c16
-rw-r--r--libc/misc/time/Makefile.in39
-rw-r--r--libc/misc/time/adjtime.c1
-rw-r--r--libc/misc/time/ftime.c12
-rw-r--r--libc/misc/time/time.c554
-rw-r--r--libc/misc/ttyent/Makefile.in16
-rw-r--r--libc/misc/ttyent/getttyent.c23
-rw-r--r--libc/misc/utmp/Makefile.in17
-rw-r--r--libc/misc/utmp/utent.c315
-rw-r--r--libc/misc/utmp/wtent.c58
-rw-r--r--libc/misc/wchar/Makefile.in20
-rw-r--r--libc/misc/wchar/wchar.c356
-rw-r--r--libc/misc/wctype/Makefile.in24
-rw-r--r--libc/misc/wctype/_wctype.c523
-rw-r--r--libc/misc/wordexp/Makefile.in16
-rw-r--r--libc/misc/wordexp/wordexp.c127
115 files changed, 4324 insertions, 3737 deletions
diff --git a/libc/misc/Makefile.in b/libc/misc/Makefile.in
index 104db366e..e01b3dcbd 100644
--- a/libc/misc/Makefile.in
+++ b/libc/misc/Makefile.in
@@ -12,14 +12,17 @@ include $(top_srcdir)libc/misc/assert/Makefile.in
include $(top_srcdir)libc/misc/ctype/Makefile.in
include $(top_srcdir)libc/misc/dirent/Makefile.in
include $(top_srcdir)libc/misc/error/Makefile.in
+include $(top_srcdir)libc/misc/elf/Makefile.in
include $(top_srcdir)libc/misc/file/Makefile.in
include $(top_srcdir)libc/misc/fnmatch/Makefile.in
include $(top_srcdir)libc/misc/ftw/Makefile.in
+include $(top_srcdir)libc/misc/fts/Makefile.in
include $(top_srcdir)libc/misc/glob/Makefile.in
include $(top_srcdir)libc/misc/gnu/Makefile.in
include $(top_srcdir)libc/misc/internals/Makefile.in
include $(top_srcdir)libc/misc/locale/Makefile.in
include $(top_srcdir)libc/misc/mntent/Makefile.in
+include $(top_srcdir)libc/misc/pthread/Makefile.in
include $(top_srcdir)libc/misc/regex/Makefile.in
include $(top_srcdir)libc/misc/search/Makefile.in
include $(top_srcdir)libc/misc/statfs/Makefile.in
diff --git a/libc/misc/assert/Makefile.in b/libc/misc/assert/Makefile.in
index 3c9111e68..aba8a3b8d 100644
--- a/libc/misc/assert/Makefile.in
+++ b/libc/misc/assert/Makefile.in
@@ -1,21 +1,23 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := __assert.c
+subdirs += libc/misc/assert
+
+CSRC-y := __assert.c
MISC_ASSERT_DIR := $(top_srcdir)libc/misc/assert
MISC_ASSERT_OUT := $(top_builddir)libc/misc/assert
-MISC_ASSERT_SRC := $(MISC_ASSERT_DIR)/__assert.c
-MISC_ASSERT_OBJ := $(MISC_ASSERT_OUT)/__assert.o
+MISC_ASSERT_SRC := $(patsubst %.c,$(MISC_ASSERT_DIR)/%.c,$(CSRC-y))
+MISC_ASSERT_OBJ := $(patsubst %.c,$(MISC_ASSERT_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_ASSERT_OBJ)
-objclean-y += misc_assert_objclean
+objclean-y += CLEAN_libc/misc/assert
-misc_assert_objclean:
- $(RM) $(MISC_ASSERT_OUT)/*.{o,os}
+CLEAN_libc/misc/assert:
+ $(do_rm) $(addprefix $(MISC_ASSERT_OUT)/*., o os)
diff --git a/libc/misc/assert/__assert.c b/libc/misc/assert/__assert.c
index 7a2fa1dce..85cedbfc2 100644
--- a/libc/misc/assert/__assert.c
+++ b/libc/misc/assert/__assert.c
@@ -13,8 +13,8 @@
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
*/
/* Oct 28, 2002
@@ -30,24 +30,19 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <bits/uClibc_uintmaxtostr.h>
-
-libc_hidden_proto(fprintf)
-libc_hidden_proto(abort)
/* Get the prototype from assert.h as a double-check. */
#undef NDEBUG
#include <assert.h>
#undef assert
-libc_hidden_proto(__assert)
#define ASSERT_SHOW_PROGNAME 1
static smallint in_assert; /* bss inits to 0. */
-void attribute_noreturn __assert(const char *assertion, const char * filename,
- int linenumber, register const char * function)
+void __assert(const char *assertion, const char * filename,
+ unsigned int linenumber, register const char * function)
{
if (!in_assert) {
in_assert = 1;
@@ -65,7 +60,7 @@ void attribute_noreturn __assert(const char *assertion, const char * filename,
assertion
);
}
+ /* shouldn't we? fflush(stderr); */
abort();
}
-
libc_hidden_def(__assert)
diff --git a/libc/misc/ctype/Makefile.in b/libc/misc/ctype/Makefile.in
index 1fc768ee3..0ebaec285 100644
--- a/libc/misc/ctype/Makefile.in
+++ b/libc/misc/ctype/Makefile.in
@@ -1,38 +1,36 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
+subdirs += libc/misc/ctype
+
# multi source ctype.c
-COM_SRC := \
- isalnum.c isalpha.c isascii.c iscntrl.c isdigit.c \
+COM_SRC-y := \
+ isalnum.c isalpha.c iscntrl.c isdigit.c \
isgraph.c islower.c isprint.c ispunct.c isspace.c \
- isupper.c isxdigit.c toascii.c tolower.c toupper.c \
+ isupper.c isxdigit.c tolower.c toupper.c \
isblank.c
+COM_SRC-$(UCLIBC_SUSV4_LEGACY) += isascii.c toascii.c
+CSRC-y := $(COM_SRC-y)
-CSRC := $(COM_SRC)
-
-ifeq ($(UCLIBC_HAS_CTYPE_TABLES),y)
-CSRC += __C_ctype_b.c __C_ctype_tolower.c __C_ctype_toupper.c \
+CSRC-$(UCLIBC_HAS_CTYPE_TABLES) += \
+ __C_ctype_b.c __C_ctype_tolower.c __C_ctype_toupper.c \
__ctype_b_loc.c __ctype_tolower_loc.c __ctype_toupper_loc.c \
__ctype_assert.c isctype.c
-endif
-
-ifeq ($(UCLIBC_HAS_XLOCALE),y)
-CSRC += $(patsubst %.c,%_l.c,$(COM_SRC))
-endif
+CSRC-$(UCLIBC_HAS_XLOCALE) += $(patsubst %.c,%_l.c,$(COM_SRC-y))
MISC_CTYPE_DIR := $(top_srcdir)libc/misc/ctype
MISC_CTYPE_OUT := $(top_builddir)libc/misc/ctype
-MISC_CTYPE_SRC := $(patsubst %.c,$(MISC_CTYPE_DIR)/%.c,$(CSRC))
-MISC_CTYPE_OBJ := $(patsubst %.c,$(MISC_CTYPE_OUT)/%.o,$(CSRC))
+MISC_CTYPE_SRC := $(patsubst %.c,$(MISC_CTYPE_DIR)/%.c,$(CSRC-y))
+MISC_CTYPE_OBJ := $(patsubst %.c,$(MISC_CTYPE_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_CTYPE_OBJ)
-objclean-y += misc_ctype_objclean
+objclean-y += CLEAN_libc/misc/ctype
-misc_ctype_objclean:
- $(RM) $(MISC_CTYPE_OUT)/*.{o,os}
+CLEAN_libc/misc/ctype:
+ $(do_rm) $(addprefix $(MISC_CTYPE_OUT)/*., o os)
diff --git a/libc/misc/ctype/ctype.c b/libc/misc/ctype/ctype.c
index abb76ebdc..db8061d9f 100644
--- a/libc/misc/ctype/ctype.c
+++ b/libc/misc/ctype/ctype.c
@@ -11,8 +11,8 @@
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
*/
/* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
@@ -35,15 +35,6 @@
#include <stdint.h>
#include <assert.h>
#include <locale.h>
-#ifdef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_b_loc)
-#elif defined __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__ctype_b)
-#endif
-
-#ifdef __UCLIBC_HAS_XLOCALE__
-#include <xlocale.h>
-#endif /* __UCLIBC_HAS_XLOCALE__ */
/**********************************************************************/
#ifdef __UCLIBC_HAS_CTYPE_TABLES__
@@ -89,14 +80,17 @@ libc_hidden_proto(__ctype_b)
#undef CTYPE_NAME
#undef ISCTYPE
#undef CTYPE_ALIAS
+#undef CTYPE_DEF
#ifdef __UCLIBC_DO_XLOCALE
#define CTYPE_NAME(X) __is ## X ## _l
#define ISCTYPE(C,F) __isctype_l( C, F, locale_arg)
-#define CTYPE_ALIAS(NAME) strong_alias( __is ## NAME ## _l , is ## NAME ## _l)
+#define CTYPE_ALIAS(NAME) strong_alias( __is ## NAME ## _l , is ## NAME ## _l)
+#define CTYPE_DEF(NAME) libc_hidden_def(is ## NAME ## _l)
#else
#define CTYPE_NAME(X) is ## X
#define ISCTYPE(C,F) __isctype( C, F )
#define CTYPE_ALIAS(NAME)
+#define CTYPE_DEF(NAME) libc_hidden_def(is ## NAME)
#endif
@@ -142,13 +136,14 @@ int CTYPE_NAME(NAME) (int c __LOCALE_PARAM ) \
{ \
CTYPE_BODY(NAME,c,PASTE2(_IS,NAME)) \
} \
+CTYPE_DEF(NAME) \
CTYPE_ALIAS(NAME)
-
#else /* __UCLIBC_HAS_CTYPE_TABLES__ */
#define C_MACRO(X) PASTE2(__C_is,X)(c)
#define CTYPE_NAME(X) is ## X
+#define CTYPE_DEF(NAME) libc_hidden_def(is ## NAME)
#define IS_FUNC_BODY(NAME) \
int CTYPE_NAME(NAME) (int c) \
@@ -161,8 +156,6 @@ int CTYPE_NAME(NAME) (int c) \
#ifdef L___ctype_assert
#ifdef __UCLIBC_HAS_CTYPE_ENFORCED__
-libc_hidden_proto(fprintf)
-libc_hidden_proto(abort)
attribute_hidden void __isctype_assert(int c, int mask)
{
@@ -220,7 +213,7 @@ int CTYPE_NAME(digit) (int C __LOCALE_PARAM)
return __isdigit_int(C); /* C could be invalid. */
#endif
}
-
+CTYPE_DEF(digit)
CTYPE_ALIAS(digit)
#else /* __UCLIBC_HAS_CTYPE_TABLES__ */
@@ -276,12 +269,6 @@ IS_FUNC_BODY(xdigit);
#ifdef L_tolower
#undef tolower
-#ifdef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_tolower_loc)
-#elif defined __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__ctype_tolower)
-#endif
-libc_hidden_proto(tolower)
#ifdef __UCLIBC_HAS_CTYPE_TABLES__
int tolower(int c)
@@ -307,7 +294,6 @@ libc_hidden_def(tolower)
#ifdef L_tolower_l
#undef tolower_l
-libc_hidden_proto(tolower_l)
int tolower_l(int c, __locale_t l)
{
#if defined(__UCLIBC_HAS_CTYPE_ENFORCED__)
@@ -316,19 +302,12 @@ int tolower_l(int c, __locale_t l)
return __UCLIBC_CTYPE_IN_TO_DOMAIN(c) ? l->__ctype_tolower[c] : c;
}
libc_hidden_def(tolower_l)
-weak_alias (tolower_l, __tolower_l)
#endif
/**********************************************************************/
#ifdef L_toupper
#undef toupper
-#ifdef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_toupper_loc)
-#elif defined __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__ctype_toupper)
-#endif
-libc_hidden_proto(toupper)
#ifdef __UCLIBC_HAS_CTYPE_TABLES__
int toupper(int c)
@@ -354,7 +333,6 @@ libc_hidden_def(toupper)
#ifdef L_toupper_l
#undef toupper_l
-libc_hidden_proto(toupper_l)
int toupper_l(int c, __locale_t l)
{
#if defined(__UCLIBC_HAS_CTYPE_ENFORCED__)
@@ -362,8 +340,6 @@ int toupper_l(int c, __locale_t l)
#endif
return __UCLIBC_CTYPE_IN_TO_DOMAIN(c) ? l->__ctype_toupper[c] : c;
}
-libc_hidden_def(toupper_l)
-weak_alias (toupper_l, __toupper_l)
#endif
/**********************************************************************/
@@ -379,14 +355,14 @@ int __XL_NPP(isascii)(int c)
#else /* __UCLIBC_HAS_CTYPE_TABLES__ */
-libc_hidden_proto(isascii)
int isascii(int c)
{
return __isascii(c); /* locale-independent */
}
-libc_hidden_def(isascii)
#endif /* __UCLIBC_HAS_CTYPE_TABLES__ */
+CTYPE_DEF(ascii)
+
#endif
/**********************************************************************/
@@ -428,7 +404,7 @@ int isctype(int c, int mask)
const __ctype_mask_t **__ctype_b_loc(void)
{
- return &(__UCLIBC_CURLOCALE_DATA).__ctype_b;
+ return &(__UCLIBC_CURLOCALE->__ctype_b);
}
libc_hidden_def(__ctype_b_loc)
@@ -440,10 +416,9 @@ libc_hidden_def(__ctype_b_loc)
#ifdef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_tolower_loc)
const __ctype_touplow_t **__ctype_tolower_loc(void)
{
- return &(__UCLIBC_CURLOCALE_DATA).__ctype_tolower;
+ return &(__UCLIBC_CURLOCALE->__ctype_tolower);
}
libc_hidden_def(__ctype_tolower_loc)
@@ -455,10 +430,9 @@ libc_hidden_def(__ctype_tolower_loc)
#ifdef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_toupper_loc)
const __ctype_touplow_t **__ctype_toupper_loc(void)
{
- return &(__UCLIBC_CURLOCALE_DATA).__ctype_toupper;
+ return &(__UCLIBC_CURLOCALE->__ctype_toupper);
}
libc_hidden_def(__ctype_toupper_loc)
@@ -468,9 +442,7 @@ libc_hidden_def(__ctype_toupper_loc)
/**********************************************************************/
#ifdef L___C_ctype_b
-extern const __ctype_mask_t __C_ctype_b_data[];
-libc_hidden_proto(__C_ctype_b_data)
-const __ctype_mask_t __C_ctype_b_data[] = {
+static const __ctype_mask_t __C_ctype_b_data[] = {
#ifdef __UCLIBC_HAS_CTYPE_SIGNED__
/* -128 M-^@ */ 0,
/* -127 M-^A */ 0,
@@ -858,9 +830,7 @@ const __ctype_mask_t __C_ctype_b_data[] = {
/* 254 M-~ */ 0,
/* 255 M-^? */ 0
};
-libc_hidden_data_def(__C_ctype_b_data)
-libc_hidden_proto(__C_ctype_b)
const __ctype_mask_t *__C_ctype_b = __C_ctype_b_data + __UCLIBC_CTYPE_B_TBL_OFFSET;
libc_hidden_data_def(__C_ctype_b)
@@ -875,9 +845,7 @@ libc_hidden_data_def(__ctype_b)
/**********************************************************************/
#ifdef L___C_ctype_tolower
-extern const __ctype_touplow_t __C_ctype_tolower_data[];
-libc_hidden_proto(__C_ctype_tolower_data)
-const __ctype_touplow_t __C_ctype_tolower_data[] = {
+static const __ctype_touplow_t __C_ctype_tolower_data[] = {
#ifdef __UCLIBC_HAS_CTYPE_SIGNED__
-128, -127, -126, -125,
-124, -123, -122, -121,
@@ -977,18 +945,15 @@ const __ctype_touplow_t __C_ctype_tolower_data[] = {
248, 249, 250, 251,
252, 253, 254, 255
};
-libc_hidden_data_def(__C_ctype_tolower_data)
-libc_hidden_proto(__C_ctype_tolower)
-const __ctype_touplow_t *__C_ctype_tolower = __C_ctype_tolower_data
- + __UCLIBC_CTYPE_TO_TBL_OFFSET;
+const __ctype_touplow_t *__C_ctype_tolower =
+ __C_ctype_tolower_data + __UCLIBC_CTYPE_TO_TBL_OFFSET;
libc_hidden_data_def(__C_ctype_tolower)
#ifndef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_tolower)
-const __ctype_touplow_t *__ctype_tolower = __C_ctype_tolower_data
- + __UCLIBC_CTYPE_TO_TBL_OFFSET;
+const __ctype_touplow_t *__ctype_tolower =
+ __C_ctype_tolower_data + __UCLIBC_CTYPE_TO_TBL_OFFSET;
libc_hidden_data_def(__ctype_tolower)
#endif
@@ -997,9 +962,7 @@ libc_hidden_data_def(__ctype_tolower)
/**********************************************************************/
#ifdef L___C_ctype_toupper
-extern const __ctype_touplow_t __C_ctype_toupper_data[];
-libc_hidden_proto(__C_ctype_toupper_data)
-const __ctype_touplow_t __C_ctype_toupper_data[] = {
+static const __ctype_touplow_t __C_ctype_toupper_data[] = {
#ifdef __UCLIBC_HAS_CTYPE_SIGNED__
-128, -127, -126, -125,
-124, -123, -122, -121,
@@ -1099,18 +1062,15 @@ const __ctype_touplow_t __C_ctype_toupper_data[] = {
248, 249, 250, 251,
252, 253, 254, 255
};
-libc_hidden_data_def(__C_ctype_toupper_data)
-libc_hidden_proto(__C_ctype_toupper)
-const __ctype_touplow_t *__C_ctype_toupper = __C_ctype_toupper_data
- + __UCLIBC_CTYPE_TO_TBL_OFFSET;
+const __ctype_touplow_t *__C_ctype_toupper =
+ __C_ctype_toupper_data + __UCLIBC_CTYPE_TO_TBL_OFFSET;
libc_hidden_data_def(__C_ctype_toupper)
#ifndef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_toupper)
-const __ctype_touplow_t *__ctype_toupper = __C_ctype_toupper_data
- + __UCLIBC_CTYPE_TO_TBL_OFFSET;
+const __ctype_touplow_t *__ctype_toupper =
+ __C_ctype_toupper_data + __UCLIBC_CTYPE_TO_TBL_OFFSET;
libc_hidden_data_def(__ctype_toupper)
#endif
diff --git a/libc/misc/dirent/Makefile.in b/libc/misc/dirent/Makefile.in
index b35efa0b1..5cae8d44d 100644
--- a/libc/misc/dirent/Makefile.in
+++ b/libc/misc/dirent/Makefile.in
@@ -1,26 +1,28 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := alphasort.c closedir.c dirfd.c opendir.c readdir.c rewinddir.c \
- scandir.c seekdir.c telldir.c readdir_r.c
+subdirs += libc/misc/dirent
-ifeq ($(UCLIBC_HAS_LFS),y)
-CSRC += readdir64.c alphasort64.c scandir64.c readdir64_r.c
-endif
+CSRC := alphasort.c readdir.c scandir.c versionsort.c
+CSRC_R := readdir_r.c
+CSRC-y := closedir.c dirfd.c opendir.c rewinddir.c seekdir.c telldir.c $(CSRC) \
+ $(CSRC_R)
+CSRC-$(UCLIBC_HAS_LFS) += $(patsubst %.c,%64.c,$(CSRC))
+CSRC-$(UCLIBC_HAS_LFS) += $(patsubst %_r.c,%64_r.c,$(CSRC_R))
MISC_DIRENT_DIR := $(top_srcdir)libc/misc/dirent
MISC_DIRENT_OUT := $(top_builddir)libc/misc/dirent
-MISC_DIRENT_SRC := $(patsubst %.c,$(MISC_DIRENT_DIR)/%.c,$(CSRC))
-MISC_DIRENT_OBJ := $(patsubst %.c,$(MISC_DIRENT_OUT)/%.o,$(CSRC))
+MISC_DIRENT_SRC := $(patsubst %.c,$(MISC_DIRENT_DIR)/%.c,$(CSRC-y))
+MISC_DIRENT_OBJ := $(patsubst %.c,$(MISC_DIRENT_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_DIRENT_OBJ)
-objclean-y += misc_dirent_objclean
+objclean-y += CLEAN_libc/misc/dirent
-misc_dirent_objclean:
- $(RM) $(MISC_DIRENT_OUT)/*.{o,os}
+CLEAN_libc/misc/dirent:
+ $(do_rm) $(addprefix $(MISC_DIRENT_OUT)/*., o os)
diff --git a/libc/misc/dirent/alphasort.c b/libc/misc/dirent/alphasort.c
index 70aa2a516..67b3b7859 100644
--- a/libc/misc/dirent/alphasort.c
+++ b/libc/misc/dirent/alphasort.c
@@ -8,11 +8,10 @@
#include <string.h>
#include "dirstream.h"
-/* Experimentally off - libc_hidden_proto(strcmp) */
-
-int alphasort(const void * a, const void * b)
+int alphasort(const struct dirent **a, const struct dirent **b)
{
- return strcmp ((*(const struct dirent **) a)->d_name,
- (*(const struct dirent **) b)->d_name);
+ return strcoll((*a)->d_name, (*b)->d_name);
}
-
+#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64
+strong_alias_untyped(alphasort,alphasort64)
+#endif
diff --git a/libc/misc/dirent/alphasort64.c b/libc/misc/dirent/alphasort64.c
index de7a87a9a..6eb414241 100644
--- a/libc/misc/dirent/alphasort64.c
+++ b/libc/misc/dirent/alphasort64.c
@@ -5,15 +5,14 @@
*/
#include <_lfs_64.h>
-
#include <dirent.h>
-#include <string.h>
-#include "dirstream.h"
-/* Experimentally off - libc_hidden_proto(strcmp) */
+#if __WORDSIZE != 64
+# include <string.h>
+# include "dirstream.h"
-int alphasort64(const void * a, const void * b)
+int alphasort64(const struct dirent64 **a, const struct dirent64 **b)
{
- return strcmp ((*(const struct dirent64 **) a)->d_name,
- (*(const struct dirent64 **) b)->d_name);
+ return strcoll((*a)->d_name, (*b)->d_name);
}
+#endif
diff --git a/libc/misc/dirent/closedir.c b/libc/misc/dirent/closedir.c
index 3dc0bd17a..dfb53f888 100644
--- a/libc/misc/dirent/closedir.c
+++ b/libc/misc/dirent/closedir.c
@@ -9,9 +9,8 @@
#include <stdlib.h>
#include <unistd.h>
#include "dirstream.h"
+#include <not-cancel.h>
-libc_hidden_proto(closedir)
-libc_hidden_proto(close)
int closedir(DIR * dir)
{
@@ -33,6 +32,6 @@ int closedir(DIR * dir)
__UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
free(dir->dd_buf);
free(dir);
- return close(fd);
+ return close_not_cancel(fd);
}
libc_hidden_def(closedir)
diff --git a/libc/misc/dirent/dirfd.c b/libc/misc/dirent/dirfd.c
index c6f46e965..649dd4ad8 100644
--- a/libc/misc/dirent/dirfd.c
+++ b/libc/misc/dirent/dirfd.c
@@ -8,7 +8,6 @@
#include <errno.h>
#include "dirstream.h"
-libc_hidden_proto(dirfd)
int dirfd(DIR * dir)
{
diff --git a/libc/misc/dirent/dirstream.h b/libc/misc/dirent/dirstream.h
index 370886aa7..59b8bafb9 100644
--- a/libc/misc/dirent/dirstream.h
+++ b/libc/misc/dirent/dirstream.h
@@ -13,8 +13,7 @@ Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
+not, see <http://www.gnu.org/licenses/>. */
/*
* POSIX Standard: 5.1.2 Directory Operations <dirent.h>
@@ -29,18 +28,6 @@ Cambridge, MA 02139, USA. */
#include <bits/uClibc_mutex.h>
-/* For now, syscall readdir () only supports one entry at a time. It
- * will be changed in the future.
-#define NUMENT 3
-*/
-#ifndef NUMENT
-#define NUMENT 1
-#endif
-
-#define SINGLE_READDIR 11
-#define MULTI_READDIR 12
-#define NEW_READDIR 13
-
/* Directory stream type. */
struct __dirstream {
/* file descriptor */
@@ -65,10 +52,4 @@ struct __dirstream {
__UCLIBC_MUTEX(dd_lock);
}; /* stream data from opendir() */
-
-extern ssize_t __getdents(int fd, char *buf, size_t count) attribute_hidden;
-#ifdef __UCLIBC_HAS_LFS__
-extern ssize_t __getdents64 (int fd, char *buf, size_t count) attribute_hidden;
-#endif
-
#endif /* dirent.h */
diff --git a/libc/misc/dirent/opendir.c b/libc/misc/dirent/opendir.c
index 26ab91511..8af00f88c 100644
--- a/libc/misc/dirent/opendir.c
+++ b/libc/misc/dirent/opendir.c
@@ -12,14 +12,56 @@
#include <unistd.h>
#include <sys/dir.h>
#include <sys/stat.h>
+#include <not-cancel.h>
+#include <dirent.h>
#include "dirstream.h"
-libc_hidden_proto(opendir)
-libc_hidden_proto(open)
-libc_hidden_proto(fcntl)
-libc_hidden_proto(close)
-libc_hidden_proto(stat)
-libc_hidden_proto(fstat)
+static DIR *fd_to_DIR(int fd, __blksize_t size)
+{
+ DIR *ptr;
+
+ ptr = malloc(sizeof(*ptr));
+ if (!ptr)
+ return NULL;
+
+ ptr->dd_fd = fd;
+ ptr->dd_nextloc = ptr->dd_size = ptr->dd_nextoff = 0;
+ ptr->dd_max = size;
+ if (ptr->dd_max < 512)
+ ptr->dd_max = 512;
+
+ ptr->dd_buf = calloc(1, ptr->dd_max);
+ if (!ptr->dd_buf) {
+ free(ptr);
+ return NULL;
+ }
+ __UCLIBC_MUTEX_INIT_VAR(ptr->dd_lock);
+
+ return ptr;
+}
+
+DIR *fdopendir(int fd)
+{
+ int flags;
+ struct stat st;
+
+ if (fstat(fd, &st))
+ return NULL;
+ if (!S_ISDIR(st.st_mode)) {
+ __set_errno(ENOTDIR);
+ return NULL;
+ }
+
+ flags = fcntl(fd, F_GETFL);
+ if (flags == -1)
+ return NULL;
+ if ((flags & O_ACCMODE) == O_WRONLY) {
+ __set_errno(EINVAL);
+ return NULL;
+ }
+
+ return fd_to_DIR(fd, st.st_blksize);
+}
/* opendir just makes an open() call - it return NULL if it fails
* (open sets errno), otherwise it returns a DIR * pointer.
@@ -40,44 +82,36 @@ DIR *opendir(const char *name)
}
# define O_DIRECTORY 0
#endif
- if ((fd = open(name, O_RDONLY|O_NDELAY|O_DIRECTORY)) < 0)
+ fd = open_not_cancel_2(name, O_RDONLY|O_NDELAY|O_DIRECTORY|O_CLOEXEC);
+ if (fd < 0)
return NULL;
-
/* Note: we should check to make sure that between the stat() and open()
* call, 'name' didnt change on us, but that's only if O_DIRECTORY isnt
* defined and since Linux has supported it for like ever, i'm not going
* to worry about it right now (if ever). */
- if (fstat(fd, &statbuf) < 0)
- goto close_and_ret;
+
+ if (fstat(fd, &statbuf) < 0) {
+ /* this close() never fails
+ *int saved_errno;
+ *saved_errno = errno; */
+ close_not_cancel_no_status(fd);
+ /*__set_errno(saved_errno);*/
+ return NULL;
+ }
/* According to POSIX, directory streams should be closed when
* exec. From "Anna Pluzhnikov" <besp@midway.uchicago.edu>.
*/
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
- int saved_errno;
-close_and_ret:
- saved_errno = errno;
- close(fd);
- __set_errno(saved_errno);
- return NULL;
- }
- if (!(ptr = malloc(sizeof(*ptr))))
- goto nomem_close_and_ret;
+#ifndef __ASSUME_O_CLOEXEC
+ fcntl_not_cancel(fd, F_SETFD, FD_CLOEXEC);
+#endif
- ptr->dd_fd = fd;
- ptr->dd_nextloc = ptr->dd_size = ptr->dd_nextoff = 0;
- ptr->dd_max = statbuf.st_blksize;
- if (ptr->dd_max < 512)
- ptr->dd_max = 512;
+ ptr = fd_to_DIR(fd, statbuf.st_blksize);
- if (!(ptr->dd_buf = calloc(1, ptr->dd_max))) {
- free(ptr);
-nomem_close_and_ret:
- close(fd);
- __set_errno(ENOMEM);
- return NULL;
+ if (!ptr) {
+ close_not_cancel_no_status(fd);
+ /* __set_errno(ENOMEM); */
}
- __pthread_mutex_init(&(ptr->dd_lock), NULL);
return ptr;
}
libc_hidden_def(opendir)
diff --git a/libc/misc/dirent/readdir.c b/libc/misc/dirent/readdir.c
index 2fb7a7246..75171064d 100644
--- a/libc/misc/dirent/readdir.c
+++ b/libc/misc/dirent/readdir.c
@@ -4,21 +4,22 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#include <features.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
#include <dirent.h>
+#include <errno.h>
+#define __need_NULL
+#include <stddef.h>
#include "dirstream.h"
-libc_hidden_proto(readdir)
+#ifndef __READDIR
+# define __READDIR readdir
+# define __DIRENT_TYPE struct dirent
+# define __GETDENTS __getdents
+#endif
-struct dirent *readdir(DIR * dir)
+__DIRENT_TYPE *__READDIR(DIR * dir)
{
ssize_t bytes;
- struct dirent *de;
+ __DIRENT_TYPE *de;
if (!dir) {
__set_errno(EBADF);
@@ -30,7 +31,7 @@ struct dirent *readdir(DIR * dir)
do {
if (dir->dd_size <= dir->dd_nextloc) {
/* read dir->dd_max bytes of directory entries. */
- bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max);
+ bytes = __GETDENTS(dir->dd_fd, dir->dd_buf, dir->dd_max);
if (bytes <= 0) {
de = NULL;
goto all_done;
@@ -39,7 +40,7 @@ struct dirent *readdir(DIR * dir)
dir->dd_nextloc = 0;
}
- de = (struct dirent *) (((char *) dir->dd_buf) + dir->dd_nextloc);
+ de = (__DIRENT_TYPE *) (((char *) dir->dd_buf) + dir->dd_nextloc);
/* Am I right? H.J. */
dir->dd_nextloc += de->d_reclen;
@@ -54,4 +55,8 @@ all_done:
__UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
return de;
}
-libc_hidden_def(readdir)
+libc_hidden_def(__READDIR)
+#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64
+strong_alias_untyped(readdir,readdir64)
+libc_hidden_def(readdir64)
+#endif
diff --git a/libc/misc/dirent/readdir64.c b/libc/misc/dirent/readdir64.c
index e8a29da96..17577a7b6 100644
--- a/libc/misc/dirent/readdir64.c
+++ b/libc/misc/dirent/readdir64.c
@@ -5,53 +5,12 @@
*/
#include <_lfs_64.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
#include <dirent.h>
-#include "dirstream.h"
-
-libc_hidden_proto(readdir64)
-struct dirent64 *readdir64(DIR * dir)
-{
- ssize_t bytes;
- struct dirent64 *de;
-
- if (!dir) {
- __set_errno(EBADF);
- return NULL;
- }
-
- __UCLIBC_MUTEX_LOCK(dir->dd_lock);
-
- do {
- if (dir->dd_size <= dir->dd_nextloc) {
- /* read dir->dd_max bytes of directory entries. */
- bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max);
- if (bytes <= 0) {
- de = NULL;
- goto all_done;
- }
- dir->dd_size = bytes;
- dir->dd_nextloc = 0;
- }
-
- de = (struct dirent64 *) (((char *) dir->dd_buf) + dir->dd_nextloc);
-
- /* Am I right? H.J. */
- dir->dd_nextloc += de->d_reclen;
-
- /* We have to save the next offset here. */
- dir->dd_nextoff = de->d_off;
-
- /* Skip deleted files. */
- } while (de->d_ino == 0);
-all_done:
- __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
+#if __WORDSIZE != 64
+# define __READDIR readdir64
+# define __DIRENT_TYPE struct dirent64
+# define __GETDENTS __getdents64
- return de;
-}
-libc_hidden_def(readdir64)
+# include "readdir.c"
+#endif
diff --git a/libc/misc/dirent/readdir64_r.c b/libc/misc/dirent/readdir64_r.c
index 2958b1d1a..c045cbdea 100644
--- a/libc/misc/dirent/readdir64_r.c
+++ b/libc/misc/dirent/readdir64_r.c
@@ -5,64 +5,12 @@
*/
#include <_lfs_64.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
#include <dirent.h>
-#include "dirstream.h"
-
-/* Experimentally off - libc_hidden_proto(memcpy) */
-
-libc_hidden_proto(readdir64_r)
-int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result)
-{
- int ret;
- ssize_t bytes;
- struct dirent64 *de;
-
- if (!dir) {
- __set_errno(EBADF);
- return(EBADF);
- }
- de = NULL;
-
- __UCLIBC_MUTEX_LOCK(dir->dd_lock);
-
- do {
- if (dir->dd_size <= dir->dd_nextloc) {
- /* read dir->dd_max bytes of directory entries. */
- bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max);
- if (bytes <= 0) {
- *result = NULL;
- ret = (bytes==0)? 0 : errno;
- goto all_done;
- }
- dir->dd_size = bytes;
- dir->dd_nextloc = 0;
- }
-
- de = (struct dirent64 *) (((char *) dir->dd_buf) + dir->dd_nextloc);
-
- /* Am I right? H.J. */
- dir->dd_nextloc += de->d_reclen;
-
- /* We have to save the next offset here. */
- dir->dd_nextoff = de->d_off;
- /* Skip deleted files. */
- } while (de->d_ino == 0);
-
- if (de == NULL) {
- *result = NULL;
- } else {
- *result = memcpy (entry, de, de->d_reclen);
- }
- ret = 0;
-all_done:
+#if __WORDSIZE != 64
+# define __READDIR_R readdir64_r
+# define __DIRENT_TYPE struct dirent64
+# define __GETDENTS __getdents64
- __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
- return((de != NULL)? 0 : ret);
-}
-libc_hidden_def(readdir64_r)
+# include "readdir_r.c"
+#endif
diff --git a/libc/misc/dirent/readdir_r.c b/libc/misc/dirent/readdir_r.c
index 194af621f..5beebfed0 100644
--- a/libc/misc/dirent/readdir_r.c
+++ b/libc/misc/dirent/readdir_r.c
@@ -4,35 +4,38 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
+#include <dirent.h>
#include <errno.h>
-#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
+#define __need_NULL
+#include <stddef.h>
#include "dirstream.h"
-/* Experimentally off - libc_hidden_proto(memcpy) */
+#ifndef __READDIR_R
+# define __READDIR_R readdir_r
+# define __DIRENT_TYPE struct dirent
+# define __GETDENTS __getdents
+#endif
-libc_hidden_proto(readdir_r)
-int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result)
+int __READDIR_R(DIR *dir, __DIRENT_TYPE *entry, __DIRENT_TYPE **result)
{
int ret;
ssize_t bytes;
- struct dirent *de;
+ __DIRENT_TYPE *de;
if (!dir) {
__set_errno(EBADF);
return(EBADF);
}
- de = NULL;
__UCLIBC_MUTEX_LOCK(dir->dd_lock);
do {
if (dir->dd_size <= dir->dd_nextloc) {
/* read dir->dd_max bytes of directory entries. */
- bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max);
+ 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;
@@ -41,7 +44,7 @@ int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result)
dir->dd_nextloc = 0;
}
- de = (struct dirent *) (((char *) dir->dd_buf) + dir->dd_nextloc);
+ de = (__DIRENT_TYPE *) (((char *) dir->dd_buf) + dir->dd_nextloc);
/* Am I right? H.J. */
dir->dd_nextloc += de->d_reclen;
@@ -63,4 +66,8 @@ all_done:
__UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
return((de != NULL)? 0 : ret);
}
-libc_hidden_def(readdir_r)
+libc_hidden_def(__READDIR_R)
+#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64
+strong_alias_untyped(readdir_r,readdir64_r)
+libc_hidden_def(readdir64_r)
+#endif
diff --git a/libc/misc/dirent/rewinddir.c b/libc/misc/dirent/rewinddir.c
index 1bbda0809..0a8f14740 100644
--- a/libc/misc/dirent/rewinddir.c
+++ b/libc/misc/dirent/rewinddir.c
@@ -9,7 +9,6 @@
#include <unistd.h>
#include "dirstream.h"
-libc_hidden_proto(lseek)
/* rewinddir() just does an lseek(fd,0,0) - see close for comments */
void rewinddir(DIR * dir)
diff --git a/libc/misc/dirent/scandir.c b/libc/misc/dirent/scandir.c
index aba63f20b..c036ce59b 100644
--- a/libc/misc/dirent/scandir.c
+++ b/libc/misc/dirent/scandir.c
@@ -1,30 +1,29 @@
+/* vi: set sw=4 ts=4: */
/*
- * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ * Copyright (C) 2000-2011 Erik Andersen <andersen@uclibc.org>
*
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
#include <dirent.h>
-#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
-#include <sys/types.h>
#include "dirstream.h"
-/* Experimentally off - libc_hidden_proto(memcpy) */
-libc_hidden_proto(readdir)
-libc_hidden_proto(opendir)
-libc_hidden_proto(closedir)
-libc_hidden_proto(qsort)
+#ifndef __SCANDIR
+# define __SCANDIR scandir
+# define __DIRENT_TYPE struct dirent
+# define __READDIR readdir
+#endif
-int scandir(const char *dir, struct dirent ***namelist,
- int (*selector) (const struct dirent *),
- int (*compar) (const void *, const void *))
+int __SCANDIR(const char *dir, __DIRENT_TYPE ***namelist,
+ int (*selector) (const __DIRENT_TYPE *),
+ int (*compar) (const __DIRENT_TYPE **, const __DIRENT_TYPE **))
{
DIR *dp = opendir (dir);
- struct dirent *current;
- struct dirent **names = NULL;
+ __DIRENT_TYPE *current;
+ __DIRENT_TYPE **names = NULL;
size_t names_size = 0, pos;
int save;
@@ -35,10 +34,21 @@ int scandir(const char *dir, struct dirent ***namelist,
__set_errno (0);
pos = 0;
- while ((current = readdir (dp)) != NULL)
- if (selector == NULL || (*selector) (current))
+ while ((current = __READDIR (dp)) != NULL) {
+ int use_it = selector == NULL;
+
+ if (! use_it)
+ {
+ use_it = (*selector) (current);
+ /* The selector function might have changed errno.
+ * It was zero before and it need to be again to make
+ * the latter tests work. */
+ if (! use_it)
+ __set_errno (0);
+ }
+ if (use_it)
{
- struct dirent *vnew;
+ __DIRENT_TYPE *vnew;
size_t dsize;
/* Ignore errors from selector or readdir */
@@ -46,24 +56,26 @@ int scandir(const char *dir, struct dirent ***namelist,
if (unlikely(pos == names_size))
{
- struct dirent **new;
+ __DIRENT_TYPE **new;
if (names_size == 0)
names_size = 10;
else
names_size *= 2;
- new = (struct dirent **) realloc (names, names_size * sizeof (struct dirent *));
+ new = (__DIRENT_TYPE **) realloc (names,
+ names_size * sizeof (__DIRENT_TYPE *));
if (new == NULL)
break;
names = new;
}
- dsize = &current->d_name[_D_ALLOC_NAMLEN (current)] - (char *) current;
- vnew = (struct dirent *) malloc (dsize);
+ dsize = &current->d_name[_D_ALLOC_NAMLEN(current)] - (char*)current;
+ vnew = (__DIRENT_TYPE *) malloc (dsize);
if (vnew == NULL)
break;
- names[pos++] = (struct dirent *) memcpy (vnew, current, dsize);
+ names[pos++] = (__DIRENT_TYPE *) memcpy (vnew, current, dsize);
}
+ }
if (unlikely(errno != 0))
{
@@ -81,7 +93,10 @@ int scandir(const char *dir, struct dirent ***namelist,
/* Sort the list if we have a comparison function to sort with. */
if (compar != NULL)
- qsort (names, pos, sizeof (struct dirent *), compar);
+ qsort (names, pos, sizeof (__DIRENT_TYPE *), (comparison_fn_t) compar);
*namelist = names;
return pos;
}
+#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64
+strong_alias_untyped(scandir,scandir64)
+#endif
diff --git a/libc/misc/dirent/scandir64.c b/libc/misc/dirent/scandir64.c
index 083d2de18..634c5d886 100644
--- a/libc/misc/dirent/scandir64.c
+++ b/libc/misc/dirent/scandir64.c
@@ -1,105 +1,16 @@
-/* Copyright (C) 1992-1998, 2000 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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA.
- */
-
-/* Modified for uClibc by Erik Andersen
- */
+/*
+ * Copyright (C) 2000-2011 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
#include <_lfs_64.h>
-
#include <dirent.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/types.h>
-#include "dirstream.h"
-
-/* Experimentally off - libc_hidden_proto(memcpy) */
-libc_hidden_proto(opendir)
-libc_hidden_proto(closedir)
-libc_hidden_proto(qsort)
-libc_hidden_proto(readdir64)
-
-int scandir64(const char *dir, struct dirent64 ***namelist,
- int (*selector) (const struct dirent64 *),
- int (*compar) (const void *, const void *))
-{
- DIR *dp = opendir (dir);
- struct dirent64 *current;
- struct dirent64 **names = NULL;
- size_t names_size = 0, pos;
- int save;
-
- if (dp == NULL)
- return -1;
-
- save = errno;
- __set_errno (0);
-
- pos = 0;
- while ((current = readdir64 (dp)) != NULL)
- if (selector == NULL || (*selector) (current))
- {
- struct dirent64 *vnew;
- size_t dsize;
-
- /* Ignore errors from selector or readdir64 */
- __set_errno (0);
-
- if (unlikely(pos == names_size))
- {
- struct dirent64 **new;
- if (names_size == 0)
- names_size = 10;
- else
- names_size *= 2;
- new = (struct dirent64 **) realloc (names, names_size * sizeof (struct dirent64 *));
- if (new == NULL)
- break;
- names = new;
- }
-
- dsize = &current->d_name[_D_ALLOC_NAMLEN (current)] - (char *) current;
- vnew = (struct dirent64 *) malloc (dsize);
- if (vnew == NULL)
- break;
-
- names[pos++] = (struct dirent64 *) memcpy (vnew, current, dsize);
- }
-
- if (unlikely(errno != 0))
- {
- save = errno;
- closedir (dp);
- while (pos > 0)
- free (names[--pos]);
- free (names);
- __set_errno (save);
- return -1;
- }
- closedir (dp);
- __set_errno (save);
+#if __WORDSIZE != 64
+# define __SCANDIR scandir64
+# define __DIRENT_TYPE struct dirent64
+# define __READDIR readdir64
- /* Sort the list if we have a comparison function to sort with. */
- if (compar != NULL)
- qsort (names, pos, sizeof (struct dirent64 *), compar);
- *namelist = names;
- return pos;
-}
+# include "scandir.c"
+#endif
diff --git a/libc/misc/dirent/seekdir.c b/libc/misc/dirent/seekdir.c
index c41844856..eaf447ea2 100644
--- a/libc/misc/dirent/seekdir.c
+++ b/libc/misc/dirent/seekdir.c
@@ -9,7 +9,6 @@
#include <unistd.h>
#include "dirstream.h"
-libc_hidden_proto(lseek)
void seekdir(DIR * dir, long int offset)
{
diff --git a/libc/misc/dirent/versionsort.c b/libc/misc/dirent/versionsort.c
new file mode 100644
index 000000000..8e56ec56b
--- /dev/null
+++ b/libc/misc/dirent/versionsort.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2008-2009 Hai Zaar, Codefidence Ltd <haizaar@codefidence.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <dirent.h>
+#include <string.h>
+#include "dirstream.h"
+
+int versionsort(const struct dirent **a, const struct dirent **b)
+{
+ return strverscmp((*a)->d_name, (*b)->d_name);
+}
+#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64
+strong_alias_untyped(versionsort,versionsort64)
+#endif
diff --git a/libc/misc/dirent/versionsort64.c b/libc/misc/dirent/versionsort64.c
new file mode 100644
index 000000000..28fef7d3f
--- /dev/null
+++ b/libc/misc/dirent/versionsort64.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2008-2009 Hai Zaar, Codefidence Ltd <haizaar@codefidence.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <_lfs_64.h>
+#include <dirent.h>
+
+#if __WORDSIZE != 64
+# include <string.h>
+# include "dirstream.h"
+
+int versionsort64(const struct dirent64 **a, const struct dirent64 **b)
+{
+ return strverscmp((*a)->d_name, (*b)->d_name);
+}
+#endif
diff --git a/libc/misc/elf/Makefile b/libc/misc/elf/Makefile
new file mode 100644
index 000000000..4bb6872a1
--- /dev/null
+++ b/libc/misc/elf/Makefile
@@ -0,0 +1,12 @@
+# Copyright (C) 2008 STMicroelectronics Ltd.
+# Author: Carmelo Amoroso <carmelo.amoroso@st.com>
+
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../
+top_builddir=../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.in
+include $(top_srcdir)Makerules
diff --git a/libc/misc/elf/Makefile.in b/libc/misc/elf/Makefile.in
new file mode 100644
index 000000000..1b4bd8bf1
--- /dev/null
+++ b/libc/misc/elf/Makefile.in
@@ -0,0 +1,22 @@
+# Copyright (C) 2008 STMicroelectronics Ltd.
+# Author: Carmelo Amoroso <carmelo.amoroso@st.com>
+
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+subdirs += libc/misc/elf
+
+libc_a_CSRC = dl-support.c dl-core.c dl-iterate-phdr.c
+CFLAGS-dl-iterate-phdr.c=-D_GNU_SOURCE -I$(top_srcdir)ldso/ldso/$(TARGET_ARCH) -I$(top_srcdir)ldso/include
+CFLAGS-dl-core.c=-I$(top_srcdir)ldso/ldso/$(TARGET_ARCH) -I$(top_srcdir)ldso/include
+
+MISC_ELF_OUT:=$(top_builddir)libc/misc/elf
+MISC_ELF_OBJ:=$(patsubst %.c,$(MISC_ELF_OUT)/%.o,$(libc_a_CSRC))
+
+libc-static-y += $(MISC_ELF_OBJ)
+libc-shared-y += $(MISC_ELF_OUT)/dl-iterate-phdr.oS
+
+objclean-y+= CLEAN_libc/misc/elf
+
+CLEAN_libc/misc/elf:
+ $(do_rm) $(addprefix $(MISC_ELF_OUT)/*., o os oS)
diff --git a/libc/misc/elf/dl-core.c b/libc/misc/elf/dl-core.c
new file mode 100644
index 000000000..b32dcf828
--- /dev/null
+++ b/libc/misc/elf/dl-core.c
@@ -0,0 +1,20 @@
+/*
+ * This contains all symbols and functions to support
+ * dynamic linking into static libc.
+
+ * Copyright (c) 2008 STMicroelectronics Ltd
+ * Author: Carmelo Amoroso <carmelo.amoroso@st.com>
+ *
+ * Based on draft work by Peter S. Mazinger <ps.m@gmx.net>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ */
+
+#ifdef SHARED
+#error "This file is not suitable for linking into dynamic libc"
+#else
+/* Include ldso symbols and functions used into static libc */
+#include "../../../ldso/ldso/dl-symbols.c"
+#endif
+
diff --git a/libc/misc/elf/dl-iterate-phdr.c b/libc/misc/elf/dl-iterate-phdr.c
new file mode 100644
index 000000000..27a92544b
--- /dev/null
+++ b/libc/misc/elf/dl-iterate-phdr.c
@@ -0,0 +1,81 @@
+/* Get loaded objects program headers.
+
+ Based on GNU C library (file: libc/elf/dl-iteratephdr.c)
+
+ Copyright (C) 2001,2002,2003,2004,2006,2007 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
+
+ Copyright (C) 2008 STMicroelectronics Ltd.
+ Author: Carmelo Amoroso <carmelo.amoroso@st.com>
+
+ Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+*/
+
+
+#include <link.h>
+#include <ldso.h>
+
+/* we want this in libc but nowhere else */
+#ifdef __USE_GNU
+
+static int
+__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data)
+{
+ int ret = 0;
+#ifndef __ARCH_HAS_NO_SHARED__
+ struct elf_resolve *l;
+ struct dl_phdr_info info;
+
+ for (l = _dl_loaded_modules; l != NULL; l = l->next) {
+ info.dlpi_addr = l->loadaddr;
+ info.dlpi_name = l->libname;
+ info.dlpi_phdr = l->ppnt;
+ info.dlpi_phnum = l->n_phent;
+ ret = callback (&info, sizeof (struct dl_phdr_info), data);
+ if (ret)
+ break;
+ }
+#endif
+ return ret;
+}
+
+# ifdef SHARED
+
+weak_alias(__dl_iterate_phdr, dl_iterate_phdr)
+
+# else
+
+/* dl-support.c defines these and initializes them early on. */
+extern ElfW(Phdr) *_dl_phdr;
+extern size_t _dl_phnum;
+
+int
+dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
+ size_t size, void *data), void *data)
+{
+ if (_dl_phnum != 0)
+ {
+ /* This entry describes this statically-linked program itself. */
+ struct dl_phdr_info info;
+ int ret;
+#if defined(__FRV_FDPIC__) || defined(__BFIN_FDPIC__)
+ info.dlpi_addr.map = NULL;
+ info.dlpi_addr.got_value = NULL;
+#elif defined(__DSBT__)
+ info.dlpi_addr.map = NULL;
+#else
+ info.dlpi_addr = 0;
+#endif
+ info.dlpi_name = "";
+ info.dlpi_phdr = _dl_phdr;
+ info.dlpi_phnum = _dl_phnum;
+ ret = (*callback) (&info, sizeof (struct dl_phdr_info), data);
+ if (ret)
+ return ret;
+ }
+ /* Then invoke callback on loaded modules, if any */
+ return __dl_iterate_phdr (callback, data);
+}
+
+# endif
+#endif
diff --git a/libc/misc/elf/dl-support.c b/libc/misc/elf/dl-support.c
new file mode 100644
index 000000000..87cd1bb72
--- /dev/null
+++ b/libc/misc/elf/dl-support.c
@@ -0,0 +1,75 @@
+/*
+ * Support for dynamic linking code in static libc.
+ * Copyright (C) 1996-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ *
+ * Partially based on GNU C Library (file: libc/elf/dl-support.c)
+ *
+ * Copyright (C) 2008 STMicroelectronics Ltd.
+ * Author: Carmelo Amoroso <carmelo.amoroso@st.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ */
+
+#include <link.h>
+#include <elf.h>
+#if defined(USE_TLS) && USE_TLS
+#include <assert.h>
+#include <tls.h>
+#include <ldsodefs.h>
+#include <string.h>
+#endif
+#include <bits/uClibc_page.h>
+
+#if defined(USE_TLS) && USE_TLS
+
+void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
+
+#endif
+
+ElfW(Phdr) *_dl_phdr;
+size_t _dl_phnum;
+size_t _dl_pagesize;
+
+void internal_function _dl_aux_init (ElfW(auxv_t) *av);
+void internal_function _dl_aux_init (ElfW(auxv_t) *av)
+{
+ /* Get the program headers base address from the aux vect */
+ _dl_phdr = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val;
+
+ /* Get the number of program headers from the aux vect */
+ _dl_phnum = (size_t) av[AT_PHNUM].a_un.a_val;
+
+ /* Get the pagesize from the aux vect */
+ _dl_pagesize = (av[AT_PAGESZ].a_un.a_val) ? (size_t) av[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
+}
+
+#if defined(USE_TLS) && USE_TLS
+/* Initialize static TLS area and DTV for current (only) thread.
+ libpthread implementations should provide their own hook
+ to handle all threads. */
+void
+attribute_hidden
+_dl_nothread_init_static_tls (struct link_map *map)
+{
+# if defined(TLS_TCB_AT_TP)
+ void *dest = (char *) THREAD_SELF - map->l_tls_offset;
+# elif defined(TLS_DTV_AT_TP)
+ void *dest = (char *) THREAD_SELF + map->l_tls_offset + TLS_PRE_TCB_SIZE;
+# else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+# endif
+
+ /* Fill in the DTV slot so that a later LD/GD access will find it. */
+ dtv_t *dtv = THREAD_DTV ();
+ assert (map->l_tls_modid <= dtv[-1].counter);
+ dtv[map->l_tls_modid].pointer.val = dest;
+ dtv[map->l_tls_modid].pointer.is_static = true;
+
+ /* Initialize the memory. */
+ memset (mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
+ '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
+}
+
+#endif
+
diff --git a/libc/misc/error/Makefile.in b/libc/misc/error/Makefile.in
index 9facacff0..fa959c131 100644
--- a/libc/misc/error/Makefile.in
+++ b/libc/misc/error/Makefile.in
@@ -1,27 +1,25 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC :=
-ifeq ($(UCLIBC_HAS_BSD_ERR),y)
-CSRC += err.c
-endif
-ifeq ($(UCLIBC_HAS_GNU_ERROR),y)
-CSRC += error.c
-endif
+subdirs += libc/misc/error
+
+CSRC-y :=
+CSRC-$(UCLIBC_HAS_BSD_ERR) += err.c
+CSRC-$(UCLIBC_HAS_GNU_ERROR) += error.c
MISC_ERROR_DIR := $(top_srcdir)libc/misc/error
MISC_ERROR_OUT := $(top_builddir)libc/misc/error
-MISC_ERROR_SRC := $(patsubst %.c,$(MISC_ERROR_DIR)/%.c,$(CSRC))
-MISC_ERROR_OBJ := $(patsubst %.c,$(MISC_ERROR_OUT)/%.o,$(CSRC))
+MISC_ERROR_SRC := $(patsubst %.c,$(MISC_ERROR_DIR)/%.c,$(CSRC-y))
+MISC_ERROR_OBJ := $(patsubst %.c,$(MISC_ERROR_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_ERROR_OBJ)
-objclean-y += misc_error_objclean
+objclean-y += CLEAN_libc/misc/error
-misc_error_objclean:
- $(RM) $(MISC_ERROR_OUT)/*.{o,os}
+CLEAN_libc/misc/error:
+ $(do_rm) $(addprefix $(MISC_ERROR_OUT)/*., o os)
diff --git a/libc/misc/error/err.c b/libc/misc/error/err.c
index ab9c8b72b..4f1e6a33f 100644
--- a/libc/misc/error/err.c
+++ b/libc/misc/error/err.c
@@ -11,9 +11,6 @@
#include <stdarg.h>
#include <errno.h>
#include <err.h>
-#ifdef __UCLIBC_HAS_THREADS__
-#include <pthread.h>
-#endif
#ifdef __UCLIBC_MJN3_ONLY__
#warning REMINDER: Deal with wide oriented stderr case.
@@ -21,16 +18,7 @@
#if defined __USE_BSD
-libc_hidden_proto(vwarn)
-libc_hidden_proto(vwarnx)
-libc_hidden_proto(verr)
-libc_hidden_proto(verrx)
-libc_hidden_proto(fprintf)
-libc_hidden_proto(vfprintf)
-libc_hidden_proto(__xpg_strerror_r)
-libc_hidden_proto(exit)
-libc_hidden_proto(vfprintf)
static void vwarn_work(const char *format, va_list args, int showerr)
{
@@ -59,68 +47,68 @@ static void vwarn_work(const char *format, va_list args, int showerr)
__STDIO_AUTO_THREADUNLOCK(stderr);
}
-void vwarn(const char *format, va_list args)
+static void __vwarn(const char *format, va_list args)
{
vwarn_work(format, args, 1);
}
-libc_hidden_def(vwarn)
+strong_alias(__vwarn,vwarn)
void warn(const char *format, ...)
{
va_list args;
va_start(args, format);
- vwarn(format, args);
+ __vwarn(format, args);
va_end(args);
}
-void vwarnx(const char *format, va_list args)
+static void __vwarnx(const char *format, va_list args)
{
vwarn_work(format, args, 0);
}
-libc_hidden_def(vwarnx)
+strong_alias(__vwarnx,vwarnx)
void warnx(const char *format, ...)
{
va_list args;
va_start(args, format);
- vwarnx(format, args);
+ __vwarnx(format, args);
va_end(args);
}
-void verr(int status, const char *format, va_list args)
+static void attribute_noreturn __verr(int status, const char *format, va_list args)
{
- vwarn(format, args);
+ __vwarn(format, args);
exit(status);
}
-libc_hidden_def(verr)
+strong_alias(__verr,verr)
-void attribute_noreturn err(int status, const char *format, ...)
+void err(int status, const char *format, ...)
{
va_list args;
va_start(args, format);
- verr(status, format, args);
+ __verr(status, format, args);
/* This should get optimized away. We'll leave it now for safety. */
/* The loop is added only to keep gcc happy. */
while(1)
va_end(args);
}
-void verrx(int status, const char *format, va_list args)
+static void attribute_noreturn __verrx(int status, const char *format, va_list args)
{
- vwarnx(format, args);
+ __vwarnx(format, args);
exit(status);
}
-libc_hidden_def(verrx)
+strong_alias(__verrx,verrx)
-void attribute_noreturn errx(int status, const char *format, ...)
+void errx(int status, const char *format, ...)
{
va_list args;
va_start(args, format);
- verrx(status, format, args);
+ __verrx(status, format, args);
/* This should get optimized away. We'll leave it now for safety. */
/* The loop is added only to keep gcc happy. */
while(1)
diff --git a/libc/misc/error/error.c b/libc/misc/error/error.c
index ed4a62ef6..d78a6f54e 100644
--- a/libc/misc/error/error.c
+++ b/libc/misc/error/error.c
@@ -13,9 +13,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
/* Adjusted slightly by Erik Andersen <andersen@uclibc.org> */
@@ -26,15 +25,6 @@
#include <string.h>
#include <error.h>
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strerror) */
-libc_hidden_proto(fprintf)
-libc_hidden_proto(exit)
-libc_hidden_proto(putc)
-libc_hidden_proto(vfprintf)
-libc_hidden_proto(fflush)
-libc_hidden_proto(fputc)
-libc_hidden_proto(__fputc_unlocked)
/* This variable is incremented each time `error' is called. */
unsigned int error_message_count = 0;
@@ -46,8 +36,7 @@ int error_one_per_line;
function without parameters instead. */
void (*error_print_progname) (void) = NULL;
-extern __typeof(error) __error attribute_hidden;
-void __error (int status, int errnum, const char *message, ...)
+void error (int status, int errnum, const char *message, ...)
{
va_list args;
@@ -69,11 +58,9 @@ void __error (int status, int errnum, const char *message, ...)
if (status)
exit (status);
}
-weak_alias(__error,error)
-extern __typeof(error_at_line) __error_at_line attribute_hidden;
-void __error_at_line (int status, int errnum, const char *file_name,
- unsigned int line_number, const char *message, ...)
+void error_at_line (int status, int errnum, const char *file_name,
+ unsigned int line_number, const char *message, ...)
{
va_list args;
@@ -112,4 +99,3 @@ void __error_at_line (int status, int errnum, const char *file_name,
if (status)
exit (status);
}
-weak_alias(__error_at_line,error_at_line)
diff --git a/libc/misc/file/Makefile.in b/libc/misc/file/Makefile.in
index 721fe5ec0..b94efa67f 100644
--- a/libc/misc/file/Makefile.in
+++ b/libc/misc/file/Makefile.in
@@ -1,24 +1,26 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
+subdirs += libc/misc/file
+
MISC_FILE_DIR := $(top_srcdir)libc/misc/file
MISC_FILE_OUT := $(top_builddir)libc/misc/file
-MISC_FILE_SRC := $(wildcard $(MISC_FILE_DIR)/*.c)
-ifneq ($(UCLIBC_HAS_LFS),y)
-MISC_FILE_SRC := $(filter-out $(MISC_FILE_DIR)/lockf64.c,$(MISC_FILE_SRC))
-endif
-MISC_FILE_OBJ := $(patsubst $(MISC_FILE_DIR)/%.c,$(MISC_FILE_OUT)/%.o,$(MISC_FILE_SRC))
+CSRC-y := $(wildcard $(MISC_FILE_DIR)/*.c)
+CSRC_LFS := $(wildcard $(MISC_FILE_DIR)/*64.c)
+CSRC-y := $(filter-out $(CSRC_LFS),$(CSRC-y))
+CSRC-$(UCLIBC_HAS_LFS) += $(CSRC_LFS)
+MISC_FILE_OBJ := $(patsubst $(MISC_FILE_DIR)/%.c,$(MISC_FILE_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_FILE_OBJ)
libc-nomulti-$(UCLIBC_HAS_LFS) += $(MISC_FILE_OUT)/lockf64.o
-objclean-y += misc_file_objclean
+objclean-y += CLEAN_libc/misc/file
-misc_file_objclean:
- $(RM) $(MISC_FILE_OUT)/*.{o,os,oS}
+CLEAN_libc/misc/file:
+ $(do_rm) $(addprefix $(MISC_FILE_OUT)/*., o os oS)
diff --git a/libc/misc/file/isfdtype.c b/libc/misc/file/isfdtype.c
new file mode 100644
index 000000000..4d9199bd1
--- /dev/null
+++ b/libc/misc/file/isfdtype.c
@@ -0,0 +1,40 @@
+/* Determine whether descriptor has given property.
+ Copyright (C) 1996-2013 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 <errno.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#ifdef __UCLIBC_HAS_LFS__
+# include <_lfs_64.h>
+#else
+# define stat64 stat
+# define fstat64 fstat
+#endif
+
+int
+isfdtype (int fildes, int fdtype)
+{
+ struct stat64 st;
+ int save_error = errno;
+ int result = fstat64 (fildes, &st);
+ __set_errno (save_error);
+ if (result)
+ return result;
+ return (st.st_mode & S_IFMT) == (mode_t) fdtype;
+}
diff --git a/libc/misc/file/issetugid.c b/libc/misc/file/issetugid.c
new file mode 100644
index 000000000..6756a1e85
--- /dev/null
+++ b/libc/misc/file/issetugid.c
@@ -0,0 +1,10 @@
+/* Copyright (C) 2013 Gentoo Foundation
+ * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+
+#include <unistd.h>
+
+int issetugid(void)
+{
+ return _pe_secure;
+}
diff --git a/libc/misc/file/lockf.c b/libc/misc/file/lockf.c
index 13b56aba4..56b3aac77 100644
--- a/libc/misc/file/lockf.c
+++ b/libc/misc/file/lockf.c
@@ -13,23 +13,15 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ see <http://www.gnu.org/licenses/>. */
#include <features.h>
-
#include <sys/types.h>
-#include <unistd.h>
#include <fcntl.h>
+#include <unistd.h>
#include <errno.h>
#include <string.h>
-libc_hidden_proto(lockf)
-
-/* Experimentally off - libc_hidden_proto(memset) */
-libc_hidden_proto(fcntl)
-libc_hidden_proto(getpid)
-
/* lockf is a simplified interface to fcntl's locking facilities. */
int lockf (int fd, int cmd, off_t len)
diff --git a/libc/misc/file/lockf64.c b/libc/misc/file/lockf64.c
index b2ffe5d8c..8d950ed8b 100644
--- a/libc/misc/file/lockf64.c
+++ b/libc/misc/file/lockf64.c
@@ -13,8 +13,7 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ see <http://www.gnu.org/licenses/>. */
#include <_lfs_64.h>
@@ -32,17 +31,12 @@
#define F_GETLK F_GETLK64
#undef F_SETLK
#define F_SETLK F_SETLK64
-libc_hidden_proto(fcntl64)
#else
-libc_hidden_proto(fcntl)
#endif
-/* Experimentally off - libc_hidden_proto(memset) */
-libc_hidden_proto(getpid)
/* lockf is a simplified interface to fcntl's locking facilities. */
-libc_hidden_proto(lockf64)
int lockf64 (int fd, int cmd, off64_t len64)
{
struct flock fl;
@@ -95,4 +89,3 @@ int lockf64 (int fd, int cmd, off64_t len64)
return fcntl(fd, cmd, &fl);
}
-libc_hidden_def(lockf64)
diff --git a/libc/misc/fnmatch/Makefile.in b/libc/misc/fnmatch/Makefile.in
index c31de9cd6..ab43e00f1 100644
--- a/libc/misc/fnmatch/Makefile.in
+++ b/libc/misc/fnmatch/Makefile.in
@@ -1,25 +1,23 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-ifeq ($(UCLIBC_HAS_FNMATCH_OLD),y)
-CSRC := fnmatch_old.c
-else
-CSRC := fnmatch.c
-endif
+subdirs += libc/misc/fnmatch
+
+CSRC-y := $(if $(UCLIBC_HAS_FNMATCH_OLD),fnmatch_old.c,fnmatch.c)
MISC_FNMATCH_DIR := $(top_srcdir)libc/misc/fnmatch
MISC_FNMATCH_OUT := $(top_builddir)libc/misc/fnmatch
-MISC_FNMATCH_SRC := $(patsubst %.c,$(MISC_FNMATCH_DIR)/%.c,$(CSRC))
-MISC_FNMATCH_OBJ := $(patsubst %.c,$(MISC_FNMATCH_OUT)/%.o,$(CSRC))
+MISC_FNMATCH_SRC := $(patsubst %.c,$(MISC_FNMATCH_DIR)/%.c,$(CSRC-y))
+MISC_FNMATCH_OBJ := $(patsubst %.c,$(MISC_FNMATCH_OUT)/%.o,$(CSRC-y))
libc-$(UCLIBC_HAS_FNMATCH) += $(MISC_FNMATCH_OBJ)
-objclean-y += misc_fnmatch_objclean
+objclean-y += CLEAN_libc/misc/fnmatch
-misc_fnmatch_objclean:
- $(RM) $(MISC_FNMATCH_OUT)/*.{o,os}
+CLEAN_libc/misc/fnmatch:
+ $(do_rm) $(addprefix $(MISC_FNMATCH_OUT)/*., o os)
diff --git a/libc/misc/fnmatch/fnmatch.c b/libc/misc/fnmatch/fnmatch.c
index 8592d4cf6..d54b6e7c7 100644
--- a/libc/misc/fnmatch/fnmatch.c
+++ b/libc/misc/fnmatch/fnmatch.c
@@ -13,14 +13,15 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
-#if HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
+/* unistd.h must be included with _LIBC defined: we need smallint */
+#include <unistd.h>
#include <features.h>
#ifdef __UCLIBC__
# undef _LIBC
@@ -41,7 +42,6 @@
#include <errno.h>
#include <fnmatch.h>
#include <ctype.h>
-#include <unistd.h>
#if HAVE_STRING_H || defined _LIBC
# include <string.h>
@@ -53,51 +53,12 @@
# include <stdlib.h>
#endif
-#ifdef __UCLIBC__
-#define __memset memset
-/* Experimentally off - libc_hidden_proto(memchr) */
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(mempcpy) */
-/* Experimentally off - libc_hidden_proto(strcat) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/*libc_hidden_proto(strchr)*/
-/*libc_hidden_proto(strchrnul)*/
-/* Experimentally off - libc_hidden_proto(strlen) */
-/* Experimentally off - libc_hidden_proto(strcoll) */
-#ifdef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_b_loc)
-libc_hidden_proto(__ctype_tolower_loc)
-#elif defined __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__ctype_b)
-libc_hidden_proto(__ctype_tolower)
-#endif
-libc_hidden_proto(tolower)
-libc_hidden_proto(fnmatch)
-libc_hidden_proto(getenv)
-#endif
-
/* For platform which support the ISO C amendement 1 functionality we
support user defined character classes. */
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
# include <wchar.h>
# include <wctype.h>
-# ifdef __UCLIBC__
-libc_hidden_proto(wctype)
-libc_hidden_proto(iswctype)
-libc_hidden_proto(btowc)
-# ifdef __UCLIBC_HAS_LOCALE__
-libc_hidden_proto(wmemchr)
-libc_hidden_proto(wmempcpy)
-libc_hidden_proto(wcscat)
-/*libc_hidden_proto(wcschr)*/
-/*libc_hidden_proto(wcschrnul)*/
-libc_hidden_proto(wcslen)
-libc_hidden_proto(wcscoll)
-libc_hidden_proto(towlower)
-libc_hidden_proto(mbsrtowcs)
-# endif
-# endif
#endif
/* We need some of the locale data (the collation sequence information)
@@ -368,13 +329,6 @@ is_char_class (const wchar_t *wcs)
# include "fnmatch_loop.c"
# endif
-#ifdef __UCLIBC_HAS_WCHAR__
-libc_hidden_proto(_stdlib_mb_cur_max)
-#else
-#undef MB_CUR_MAX
-#define MB_CUR_MAX 1
-#endif
-
int
fnmatch (const char *pattern, const char *string, int flags)
{
@@ -388,7 +342,7 @@ fnmatch (const char *pattern, const char *string, int flags)
wchar_t *wstring = NULL;
/* Convert the strings into wide characters. */
- __memset (&ps, '\0', sizeof (ps));
+ memset (&ps, '\0', sizeof (ps));
p = pattern;
#ifdef _LIBC
n = strnlen (pattern, 1024);
@@ -405,7 +359,7 @@ fnmatch (const char *pattern, const char *string, int flags)
already done? */
return -1;
if (p)
- __memset (&ps, '\0', sizeof (ps));
+ memset (&ps, '\0', sizeof (ps));
}
if (__builtin_expect (p != NULL, 0))
{
@@ -437,7 +391,7 @@ fnmatch (const char *pattern, const char *string, int flags)
already done? */
return -1;
if (p)
- __memset (&ps, '\0', sizeof (ps));
+ memset (&ps, '\0', sizeof (ps));
}
if (__builtin_expect (p != NULL, 0))
{
diff --git a/libc/misc/fnmatch/fnmatch_loop.c b/libc/misc/fnmatch/fnmatch_loop.c
index af41727c0..6d037f8f9 100644
--- a/libc/misc/fnmatch/fnmatch_loop.c
+++ b/libc/misc/fnmatch/fnmatch_loop.c
@@ -13,9 +13,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/* Match STRING against the filename pattern PATTERN, returning zero if
it matches, nonzero if not. */
@@ -508,7 +507,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,
if (symb_table[2 * elem] == hash
&& (c1
== extra[symb_table[2 * elem + 1]])
- && __memcmp (str,
+ && memcmp (str,
&extra[symb_table[2 * elem
+ 1]
+ 1], c1) == 0)
@@ -729,7 +728,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,
if (symb_table[2 * elem] == hash
&& (c1
== extra[symb_table[2 * elem + 1]])
- && __memcmp (str,
+ && memcmp (str,
&extra[symb_table[2 * elem + 1]
+ 1], c1) == 0)
{
diff --git a/libc/misc/fnmatch/fnmatch_old.c b/libc/misc/fnmatch/fnmatch_old.c
index 577e35676..8da456333 100644
--- a/libc/misc/fnmatch/fnmatch_old.c
+++ b/libc/misc/fnmatch/fnmatch_old.c
@@ -12,10 +12,9 @@ Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
+not, see <http://www.gnu.org/licenses/>. */
-#if HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -23,9 +22,7 @@ Cambridge, MA 02139, USA. */
#include <fnmatch.h>
#include <ctype.h>
-libc_hidden_proto(fnmatch)
-libc_hidden_proto(tolower)
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
diff --git a/libc/misc/fts/Makefile b/libc/misc/fts/Makefile
new file mode 100644
index 000000000..1361db3e0
--- /dev/null
+++ b/libc/misc/fts/Makefile
@@ -0,0 +1,14 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2009 STMicroelectronics Ltd.
+# Author: Salvatore Cro <salvatore.cro at st.com>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../
+top_builddir=../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.in
+include $(top_srcdir)Makerules
diff --git a/libc/misc/fts/Makefile.in b/libc/misc/fts/Makefile.in
new file mode 100644
index 000000000..aa87d993a
--- /dev/null
+++ b/libc/misc/fts/Makefile.in
@@ -0,0 +1,23 @@
+# FTS Makefile for uClibc
+#
+# Copyright (C) 2009 STMicroelectronics Ltd.
+# Author: Salvatore Cro <salvatore.cro at st.com>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+subdirs += libc/misc/fts
+CSRC-y := fts.c
+
+MISC_FTS_DIR := $(top_srcdir)libc/misc/fts
+MISC_FTS_OUT := $(top_builddir)libc/misc/fts
+
+MISC_FTS_SRC := $(patsubst %.c,$(MISC_FTS_DIR)/%.c,$(CSRC-y))
+MISC_FTS_OBJ := $(patsubst %.c,$(MISC_FTS_OUT)/%.o,$(CSRC-y))
+
+libc-$(UCLIBC_HAS_FTS) += $(MISC_FTS_OBJ)
+
+objclean-y += CLEAN_libc/misc/fts
+
+CLEAN_libc/misc/fts:
+ $(do_rm) $(addprefix $(MISC_FTS_OUT)/*., o os)
diff --git a/libc/misc/fts/fts.c b/libc/misc/fts/fts.c
new file mode 100644
index 000000000..7dc67683b
--- /dev/null
+++ b/libc/misc/fts/fts.c
@@ -0,0 +1,1114 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fts.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __UCLIBC_HAS_LFS__
+/* this is wrong, either you include this header as first, or not at all */
+# include <_lfs_64.h>
+#else
+# define stat64 stat
+# define fstat64 fstat
+#endif
+
+/* Largest alignment size needed, minus one.
+ Usually long double is the worst case. */
+#ifndef ALIGNBYTES
+#define ALIGNBYTES (__alignof__ (long double) - 1)
+#endif
+/* Align P to that size. */
+#ifndef ALIGN
+#define ALIGN(p) (((unsigned long int) (p) + ALIGNBYTES) & ~ALIGNBYTES)
+#endif
+
+
+static FTSENT *fts_alloc (FTS *, const char *, size_t) internal_function;
+static FTSENT *fts_build (FTS *, int) internal_function;
+static void fts_lfree (FTSENT *) internal_function;
+static void fts_load (FTS *, FTSENT *) internal_function;
+static size_t fts_maxarglen (char * const *) internal_function;
+static void fts_padjust (FTS *, FTSENT *) internal_function;
+static int fts_palloc (FTS *, size_t) internal_function;
+static FTSENT *fts_sort (FTS *, FTSENT *, int) internal_function;
+static u_short fts_stat (FTS *, FTSENT *, int) internal_function;
+static int fts_safe_changedir (FTS *, FTSENT *, int, const char *)
+ internal_function;
+
+#ifndef MAX
+#define MAX(a, b) ({ __typeof__ (a) _a = (a); \
+ __typeof__ (b) _b = (b); \
+ _a > _b ? _a : _b; })
+#endif
+
+#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
+
+#define CLR(opt) (sp->fts_options &= ~(opt))
+#define ISSET(opt) (sp->fts_options & (opt))
+#define SET(opt) (sp->fts_options |= (opt))
+
+#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
+
+/* fts_build flags */
+#define BCHILD 1 /* fts_children */
+#define BNAMES 2 /* fts_children, names only */
+#define BREAD 3 /* fts_read */
+
+FTS *
+fts_open( char * const *argv, register int options,
+ int (*compar) (const FTSENT **, const FTSENT **))
+{
+ register FTS *sp;
+ register FTSENT *p, *root;
+ register int nitems;
+ FTSENT *parent = NULL;
+ FTSENT *tmp = NULL;
+
+ /* Options check. */
+ if (options & ~FTS_OPTIONMASK) {
+ __set_errno (EINVAL);
+ return (NULL);
+ }
+
+ /* Allocate/initialize the stream */
+ if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
+ return (NULL);
+ memset(sp, 0, sizeof(FTS));
+ sp->fts_compar = (int (*) (const void *, const void *)) compar;
+ sp->fts_options = options;
+
+ /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
+ if (ISSET(FTS_LOGICAL))
+ SET(FTS_NOCHDIR);
+
+ /*
+ * Start out with 1K of path space, and enough, in any case,
+ * to hold the user's paths.
+ */
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+ size_t maxarglen = fts_maxarglen(argv);
+ if (fts_palloc(sp, MAX(maxarglen, MAXPATHLEN)))
+ goto mem1;
+
+ /* Allocate/initialize root's parent. */
+ if (*argv != NULL) {
+ if ((parent = fts_alloc(sp, "", 0)) == NULL)
+ goto mem2;
+ parent->fts_level = FTS_ROOTPARENTLEVEL;
+ }
+
+ /* Allocate/initialize root(s). */
+ for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
+ /* Don't allow zero-length paths. */
+ size_t len = strlen(*argv);
+ if (len == 0) {
+ __set_errno (ENOENT);
+ goto mem3;
+ }
+
+ p = fts_alloc(sp, *argv, len);
+ p->fts_level = FTS_ROOTLEVEL;
+ p->fts_parent = parent;
+ p->fts_accpath = p->fts_name;
+ p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
+
+ /* Command-line "." and ".." are real directories. */
+ if (p->fts_info == FTS_DOT)
+ p->fts_info = FTS_D;
+
+ /*
+ * If comparison routine supplied, traverse in sorted
+ * order; otherwise traverse in the order specified.
+ */
+ if (compar) {
+ p->fts_link = root;
+ root = p;
+ } else {
+ p->fts_link = NULL;
+ if (root == NULL)
+ tmp = root = p;
+ else {
+ tmp->fts_link = p;
+ tmp = p;
+ }
+ }
+ }
+ if (compar && nitems > 1)
+ root = fts_sort(sp, root, nitems);
+
+ /*
+ * Allocate a dummy pointer and make fts_read think that we've just
+ * finished the node before the root(s); set p->fts_info to FTS_INIT
+ * so that everything about the "current" node is ignored.
+ */
+ if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
+ goto mem3;
+ sp->fts_cur->fts_link = root;
+ sp->fts_cur->fts_info = FTS_INIT;
+
+ /*
+ * If using chdir(2), grab a file descriptor pointing to dot to ensure
+ * that we can get back here; this could be avoided for some paths,
+ * but almost certainly not worth the effort. Slashes, symbolic links,
+ * and ".." are all fairly nasty problems. Note, if we can't get the
+ * descriptor we run anyway, just more slowly.
+ */
+ if (!ISSET(FTS_NOCHDIR)
+ && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
+ SET(FTS_NOCHDIR);
+
+ return (sp);
+
+mem3: fts_lfree(root);
+ free(parent);
+mem2: free(sp->fts_path);
+mem1: free(sp);
+ return (NULL);
+}
+
+static void
+internal_function
+fts_load(FTS *sp, register FTSENT *p)
+{
+ register int len;
+ register char *cp;
+
+ /*
+ * Load the stream structure for the next traversal. Since we don't
+ * actually enter the directory until after the preorder visit, set
+ * the fts_accpath field specially so the chdir gets done to the right
+ * place and the user can access the first node. From fts_open it's
+ * known that the path will fit.
+ */
+ len = p->fts_pathlen = p->fts_namelen;
+ memmove(sp->fts_path, p->fts_name, len + 1);
+ if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
+ len = strlen(++cp);
+ memmove(p->fts_name, cp, len + 1);
+ p->fts_namelen = len;
+ }
+ p->fts_accpath = p->fts_path = sp->fts_path;
+ sp->fts_dev = p->fts_dev;
+}
+
+int
+fts_close(FTS *sp)
+{
+ register FTSENT *freep, *p;
+ int saved_errno;
+
+ /*
+ * This still works if we haven't read anything -- the dummy structure
+ * points to the root list, so we step through to the end of the root
+ * list which has a valid parent pointer.
+ */
+ if (sp->fts_cur) {
+ for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
+ freep = p;
+ p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
+ free(freep);
+ }
+ free(p);
+ }
+
+ /* Free up child linked list, sort array, path buffer. */
+ if (sp->fts_child)
+ fts_lfree(sp->fts_child);
+ free(sp->fts_array);
+ free(sp->fts_path);
+
+ /* Return to original directory, save errno if necessary. */
+ if (!ISSET(FTS_NOCHDIR)) {
+ saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
+ (void)close(sp->fts_rfd);
+
+ /* Set errno and return. */
+ if (saved_errno != 0) {
+ /* Free up the stream pointer. */
+ free(sp);
+ __set_errno (saved_errno);
+ return (-1);
+ }
+ }
+
+ /* Free up the stream pointer. */
+ free(sp);
+ return (0);
+}
+
+/*
+ * Special case of "/" at the end of the path so that slashes aren't
+ * appended which would cause paths to be written as "....//foo".
+ */
+#define NAPPEND(p) \
+ (p->fts_path[p->fts_pathlen - 1] == '/' \
+ ? p->fts_pathlen - 1 : p->fts_pathlen)
+
+FTSENT *
+fts_read(register FTS *sp)
+{
+ register FTSENT *p, *tmp;
+ register int instr;
+ register char *t;
+ int saved_errno;
+
+ /* If finished or unrecoverable error, return NULL. */
+ if (sp->fts_cur == NULL || ISSET(FTS_STOP))
+ return (NULL);
+
+ /* Set current node pointer. */
+ p = sp->fts_cur;
+
+ /* Save and zero out user instructions. */
+ instr = p->fts_instr;
+ p->fts_instr = FTS_NOINSTR;
+
+ /* Any type of file may be re-visited; re-stat and re-turn. */
+ if (instr == FTS_AGAIN) {
+ p->fts_info = fts_stat(sp, p, 0);
+ return (p);
+ }
+
+ /*
+ * Following a symlink -- SLNONE test allows application to see
+ * SLNONE and recover. If indirecting through a symlink, have
+ * keep a pointer to current location. If unable to get that
+ * pointer, follow fails.
+ */
+ if (instr == FTS_FOLLOW &&
+ (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
+ p->fts_info = fts_stat(sp, p, 1);
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
+ if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
+ p->fts_errno = errno;
+ p->fts_info = FTS_ERR;
+ } else
+ p->fts_flags |= FTS_SYMFOLLOW;
+ }
+ return (p);
+ }
+
+ /* Directory in pre-order. */
+ if (p->fts_info == FTS_D) {
+ /* If skipped or crossed mount point, do post-order visit. */
+ if (instr == FTS_SKIP ||
+ (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
+ if (p->fts_flags & FTS_SYMFOLLOW)
+ (void)close(p->fts_symfd);
+ if (sp->fts_child) {
+ fts_lfree(sp->fts_child);
+ sp->fts_child = NULL;
+ }
+ p->fts_info = FTS_DP;
+ return (p);
+ }
+
+ /* Rebuild if only read the names and now traversing. */
+ if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) {
+ CLR(FTS_NAMEONLY);
+ fts_lfree(sp->fts_child);
+ sp->fts_child = NULL;
+ }
+
+ /*
+ * Cd to the subdirectory.
+ *
+ * If have already read and now fail to chdir, whack the list
+ * to make the names come out right, and set the parent errno
+ * so the application will eventually get an error condition.
+ * Set the FTS_DONTCHDIR flag so that when we logically change
+ * directories back to the parent we don't do a chdir.
+ *
+ * If haven't read do so. If the read fails, fts_build sets
+ * FTS_STOP or the fts_info field of the node.
+ */
+ if (sp->fts_child != NULL) {
+ if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
+ p->fts_errno = errno;
+ p->fts_flags |= FTS_DONTCHDIR;
+ for (p = sp->fts_child; p != NULL;
+ p = p->fts_link)
+ p->fts_accpath =
+ p->fts_parent->fts_accpath;
+ }
+ } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
+ if (ISSET(FTS_STOP))
+ return (NULL);
+ return (p);
+ }
+ p = sp->fts_child;
+ sp->fts_child = NULL;
+ sp->fts_cur = p;
+ goto name;
+ }
+
+ /* Move to the next node on this level. */
+next: tmp = p;
+ if ((p = p->fts_link) != NULL) {
+ sp->fts_cur = p;
+ free(tmp);
+
+ /*
+ * If reached the top, return to the original directory (or
+ * the root of the tree), and load the paths for the next root.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ fts_load(sp, p);
+ return p;
+ }
+
+ /*
+ * User may have called fts_set on the node. If skipped,
+ * ignore. If followed, get a file descriptor so we can
+ * get back if necessary.
+ */
+ if (p->fts_instr == FTS_SKIP)
+ goto next;
+ if (p->fts_instr == FTS_FOLLOW) {
+ p->fts_info = fts_stat(sp, p, 1);
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
+ if ((p->fts_symfd =
+ open(".", O_RDONLY, 0)) < 0) {
+ p->fts_errno = errno;
+ p->fts_info = FTS_ERR;
+ } else
+ p->fts_flags |= FTS_SYMFOLLOW;
+ }
+ p->fts_instr = FTS_NOINSTR;
+ }
+
+name: t = sp->fts_path + NAPPEND(p->fts_parent);
+ *t++ = '/';
+ memmove(t, p->fts_name, p->fts_namelen + 1);
+ return p;
+ }
+
+ /* Move up to the parent node. */
+ p = tmp->fts_parent;
+ sp->fts_cur = p;
+ free(tmp);
+
+ if (p->fts_level == FTS_ROOTPARENTLEVEL) {
+ /*
+ * Done; free everything up and set errno to 0 so the user
+ * can distinguish between error and EOF.
+ */
+ free(p);
+ __set_errno (0);
+ return (sp->fts_cur = NULL);
+ }
+
+ /* NUL terminate the pathname. */
+ sp->fts_path[p->fts_pathlen] = '\0';
+
+ /*
+ * Return to the parent directory. If at a root node or came through
+ * a symlink, go back through the file descriptor. Otherwise, cd up
+ * one directory.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ } else if (p->fts_flags & FTS_SYMFOLLOW) {
+ if (FCHDIR(sp, p->fts_symfd)) {
+ saved_errno = errno;
+ (void)close(p->fts_symfd);
+ __set_errno (saved_errno);
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ (void)close(p->fts_symfd);
+ } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
+ fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
+ return p;
+}
+
+/*
+ * Fts_set takes the stream as an argument although it's not used in this
+ * implementation; it would be necessary if anyone wanted to add global
+ * semantics to fts using fts_set. An error return is allowed for similar
+ * reasons.
+ */
+/* ARGSUSED */
+int
+fts_set(FTS *sp, FTSENT *p, int instr)
+{
+ if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
+ instr != FTS_NOINSTR && instr != FTS_SKIP) {
+ __set_errno (EINVAL);
+ return (1);
+ }
+ p->fts_instr = instr;
+ return (0);
+}
+
+FTSENT *
+fts_children(register FTS *sp, int instr)
+{
+ register FTSENT *p;
+ int fd;
+
+ if (instr != 0 && instr != FTS_NAMEONLY) {
+ __set_errno (EINVAL);
+ return (NULL);
+ }
+
+ /* Set current node pointer. */
+ p = sp->fts_cur;
+
+ /*
+ * Errno set to 0 so user can distinguish empty directory from
+ * an error.
+ */
+ __set_errno (0);
+
+ /* Fatal errors stop here. */
+ if (ISSET(FTS_STOP))
+ return (NULL);
+
+ /* Return logical hierarchy of user's arguments. */
+ if (p->fts_info == FTS_INIT)
+ return (p->fts_link);
+
+ /*
+ * If not a directory being visited in pre-order, stop here. Could
+ * allow FTS_DNR, assuming the user has fixed the problem, but the
+ * same effect is available with FTS_AGAIN.
+ */
+ if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
+ return (NULL);
+
+ /* Free up any previous child list. */
+ if (sp->fts_child != NULL)
+ fts_lfree(sp->fts_child);
+
+ if (instr == FTS_NAMEONLY) {
+ SET(FTS_NAMEONLY);
+ instr = BNAMES;
+ } else
+ instr = BCHILD;
+
+ /*
+ * If using chdir on a relative path and called BEFORE fts_read does
+ * its chdir to the root of a traversal, we can lose -- we need to
+ * chdir into the subdirectory, and we don't know where the current
+ * directory is, so we can't get back so that the upcoming chdir by
+ * fts_read will work.
+ */
+ if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
+ ISSET(FTS_NOCHDIR))
+ return (sp->fts_child = fts_build(sp, instr));
+
+ if ((fd = open(".", O_RDONLY, 0)) < 0)
+ return (NULL);
+ sp->fts_child = fts_build(sp, instr);
+ if (fchdir(fd))
+ return (NULL);
+ (void)close(fd);
+ return (sp->fts_child);
+}
+
+/*
+ * This is the tricky part -- do not casually change *anything* in here. The
+ * idea is to build the linked list of entries that are used by fts_children
+ * and fts_read. There are lots of special cases.
+ *
+ * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
+ * set and it's a physical walk (so that symbolic links can't be directories),
+ * we can do things quickly. First, if it's a 4.4BSD file system, the type
+ * of the file is in the directory entry. Otherwise, we assume that the number
+ * of subdirectories in a node is equal to the number of links to the parent.
+ * The former skips all stat calls. The latter skips stat calls in any leaf
+ * directories and for any files after the subdirectories in the directory have
+ * been found, cutting the stat calls by about 2/3.
+ */
+static FTSENT *
+internal_function
+fts_build(register FTS *sp, int type)
+{
+ register struct dirent *dp;
+ register FTSENT *p, *head;
+ register int nitems;
+ FTSENT *cur, *tail;
+ DIR *dirp;
+ void *oldaddr;
+ int /*cderrno,*/ descend, len, level, nlinks, saved_errno,
+ nostat, doadjust;
+ size_t maxlen;
+ char *cp;
+
+ /* Set current node pointer. */
+ cur = sp->fts_cur;
+
+ /*
+ * Open the directory for reading. If this fails, we're done.
+ * If being called from fts_read, set the fts_info field.
+ */
+#if defined FTS_WHITEOUT && 0
+ if (ISSET(FTS_WHITEOUT))
+ oflag = DTF_NODUP|DTF_REWIND;
+ else
+ oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
+#else
+# define opendir2(path, flag) opendir(path)
+#endif
+ if ((dirp = opendir2(cur->fts_accpath, oflag)) == NULL) {
+ if (type == BREAD) {
+ cur->fts_info = FTS_DNR;
+ cur->fts_errno = errno;
+ }
+ return (NULL);
+ }
+
+ /*
+ * Nlinks is the number of possible entries of type directory in the
+ * directory if we're cheating on stat calls, 0 if we're not doing
+ * any stat calls at all, -1 if we're doing stats on everything.
+ */
+ if (type == BNAMES) {
+ nlinks = 0;
+ /* Be quiet about nostat, GCC. */
+ nostat = 0;
+ } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
+ nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
+ nostat = 1;
+ } else {
+ nlinks = -1;
+ nostat = 0;
+ }
+
+#ifdef notdef
+ (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);
+ (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",
+ ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT));
+#endif
+ /*
+ * If we're going to need to stat anything or we want to descend
+ * and stay in the directory, chdir. If this fails we keep going,
+ * but set a flag so we don't chdir after the post-order visit.
+ * We won't be able to stat anything, but we can still return the
+ * names themselves. Note, that since fts_read won't be able to
+ * chdir into the directory, it will have to return different path
+ * names than before, i.e. "a/b" instead of "b". Since the node
+ * has already been visited in pre-order, have to wait until the
+ * post-order visit to return the error. There is a special case
+ * here, if there was nothing to stat then it's not an error to
+ * not be able to stat. This is all fairly nasty. If a program
+ * needed sorted entries or stat information, they had better be
+ * checking FTS_NS on the returned nodes.
+ */
+ /* cderrno = 0; */
+ if (nlinks || type == BREAD) {
+ if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
+ if (nlinks && type == BREAD)
+ cur->fts_errno = errno;
+ cur->fts_flags |= FTS_DONTCHDIR;
+ descend = 0;
+ /* cderrno = errno; */
+ (void)closedir(dirp);
+ dirp = NULL;
+ } else
+ descend = 1;
+ } else
+ descend = 0;
+
+ /*
+ * Figure out the max file name length that can be stored in the
+ * current path -- the inner loop allocates more path as necessary.
+ * We really wouldn't have to do the maxlen calculations here, we
+ * could do them in fts_read before returning the path, but it's a
+ * lot easier here since the length is part of the dirent structure.
+ *
+ * If not changing directories set a pointer so that can just append
+ * each new name into the path.
+ */
+ len = NAPPEND(cur);
+ if (ISSET(FTS_NOCHDIR)) {
+ cp = sp->fts_path + len;
+ *cp++ = '/';
+ } else {
+ /* GCC, you're too verbose. */
+ cp = NULL;
+ }
+ len++;
+ maxlen = sp->fts_pathlen - len;
+
+ level = cur->fts_level + 1;
+
+ /* Read the directory, attaching each entry to the `link' pointer. */
+ doadjust = 0;
+ for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
+ if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
+ continue;
+
+ if ((p = fts_alloc(sp, dp->d_name, _D_EXACT_NAMLEN (dp))) == NULL)
+ goto mem1;
+ if (_D_EXACT_NAMLEN (dp) >= maxlen) {/* include space for NUL */
+ oldaddr = sp->fts_path;
+ if (fts_palloc(sp, _D_EXACT_NAMLEN (dp) + len + 1)) {
+ /*
+ * No more memory for path or structures. Save
+ * errno, free up the current structure and the
+ * structures already allocated.
+ */
+mem1: saved_errno = errno;
+ free(p);
+ fts_lfree(head);
+ (void)closedir(dirp);
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ __set_errno (saved_errno);
+ return (NULL);
+ }
+ /* Did realloc() change the pointer? */
+ if (oldaddr != sp->fts_path) {
+ doadjust = 1;
+ if (ISSET(FTS_NOCHDIR))
+ cp = sp->fts_path + len;
+ }
+ maxlen = sp->fts_pathlen - len;
+ }
+
+ if (len + _D_EXACT_NAMLEN (dp) >= USHRT_MAX) {
+ /*
+ * In an FTSENT, fts_pathlen is a u_short so it is
+ * possible to wraparound here. If we do, free up
+ * the current structure and the structures already
+ * allocated, then error out with ENAMETOOLONG.
+ */
+ free(p);
+ fts_lfree(head);
+ (void)closedir(dirp);
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ __set_errno (ENAMETOOLONG);
+ return (NULL);
+ }
+ p->fts_level = level;
+ p->fts_parent = sp->fts_cur;
+ p->fts_pathlen = len + _D_EXACT_NAMLEN (dp);
+
+#if defined FTS_WHITEOUT && 0
+ if (dp->d_type == DT_WHT)
+ p->fts_flags |= FTS_ISW;
+#endif
+
+#if 0
+ /* Unreachable code. cderrno is only ever set to a nonnull
+ value if dirp is closed at the same time. But then we
+ cannot enter this loop. */
+ if (cderrno) {
+ if (nlinks) {
+ p->fts_info = FTS_NS;
+ p->fts_errno = cderrno;
+ } else
+ p->fts_info = FTS_NSOK;
+ p->fts_accpath = cur->fts_accpath;
+ } else
+#endif
+ if (nlinks == 0
+#if defined DT_DIR && defined _DIRENT_HAVE_D_TYPE
+ || (nostat &&
+ dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
+#endif
+ ) {
+ p->fts_accpath =
+ ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
+ p->fts_info = FTS_NSOK;
+ } else {
+ /* Build a file name for fts_stat to stat. */
+ if (ISSET(FTS_NOCHDIR)) {
+ p->fts_accpath = p->fts_path;
+ memmove(cp, p->fts_name, p->fts_namelen + 1);
+ } else
+ p->fts_accpath = p->fts_name;
+ /* Stat it. */
+ p->fts_info = fts_stat(sp, p, 0);
+
+ /* Decrement link count if applicable. */
+ if (nlinks > 0 && (p->fts_info == FTS_D ||
+ p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
+ --nlinks;
+ }
+
+ /* We walk in directory order so "ls -f" doesn't get upset. */
+ p->fts_link = NULL;
+ if (head == NULL)
+ head = tail = p;
+ else {
+ tail->fts_link = p;
+ tail = p;
+ }
+ ++nitems;
+ }
+ if (dirp)
+ (void)closedir(dirp);
+
+ /*
+ * If realloc() changed the address of the path, adjust the
+ * addresses for the rest of the tree and the dir list.
+ */
+ if (doadjust)
+ fts_padjust(sp, head);
+
+ /*
+ * If not changing directories, reset the path back to original
+ * state.
+ */
+ if (ISSET(FTS_NOCHDIR)) {
+ if (len == sp->fts_pathlen || nitems == 0)
+ --cp;
+ *cp = '\0';
+ }
+
+ /*
+ * If descended after called from fts_children or after called from
+ * fts_read and nothing found, get back. At the root level we use
+ * the saved fd; if one of fts_open()'s arguments is a relative path
+ * to an empty directory, we wind up here with no other way back. If
+ * can't get back, we're done.
+ */
+ if (descend && (type == BCHILD || !nitems) &&
+ (cur->fts_level == FTS_ROOTLEVEL ?
+ FCHDIR(sp, sp->fts_rfd) :
+ fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ fts_lfree(head);
+ return (NULL);
+ }
+
+ /* If didn't find anything, return NULL. */
+ if (!nitems) {
+ if (type == BREAD)
+ cur->fts_info = FTS_DP;
+ fts_lfree(head);
+ return (NULL);
+ }
+
+ /* Sort the entries. */
+ if (sp->fts_compar && nitems > 1)
+ head = fts_sort(sp, head, nitems);
+ return (head);
+}
+
+static u_short
+internal_function
+fts_stat(FTS *sp, register FTSENT *p, int follow)
+{
+ register FTSENT *t;
+ register dev_t dev;
+ register ino_t ino;
+ struct stat *sbp, sb;
+ int saved_errno;
+
+ /* If user needs stat info, stat buffer already allocated. */
+ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
+
+#if defined FTS_WHITEOUT && 0
+ /* check for whiteout */
+ if (p->fts_flags & FTS_ISW) {
+ if (sbp != &sb) {
+ memset(sbp, '\0', sizeof (*sbp));
+ sbp->st_mode = S_IFWHT;
+ }
+ return (FTS_W);
+ }
+#endif
+
+ /*
+ * If doing a logical walk, or application requested FTS_FOLLOW, do
+ * a stat(2). If that fails, check for a non-existent symlink. If
+ * fail, set the errno from the stat call.
+ */
+ if (ISSET(FTS_LOGICAL) || follow) {
+ if (stat(p->fts_accpath, sbp)) {
+ saved_errno = errno;
+ if (!lstat(p->fts_accpath, sbp)) {
+ __set_errno (0);
+ return (FTS_SLNONE);
+ }
+ p->fts_errno = saved_errno;
+ goto err;
+ }
+ } else if (lstat(p->fts_accpath, sbp)) {
+ p->fts_errno = errno;
+err: memset(sbp, 0, sizeof(struct stat));
+ return (FTS_NS);
+ }
+
+ if (S_ISDIR(sbp->st_mode)) {
+ /*
+ * Set the device/inode. Used to find cycles and check for
+ * crossing mount points. Also remember the link count, used
+ * in fts_build to limit the number of stat calls. It is
+ * understood that these fields are only referenced if fts_info
+ * is set to FTS_D.
+ */
+ dev = p->fts_dev = sbp->st_dev;
+ ino = p->fts_ino = sbp->st_ino;
+ p->fts_nlink = sbp->st_nlink;
+
+ if (ISDOT(p->fts_name))
+ return (FTS_DOT);
+
+ /*
+ * Cycle detection is done by brute force when the directory
+ * is first encountered. If the tree gets deep enough or the
+ * number of symbolic links to directories is high enough,
+ * something faster might be worthwhile.
+ */
+ for (t = p->fts_parent;
+ t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
+ if (ino == t->fts_ino && dev == t->fts_dev) {
+ p->fts_cycle = t;
+ return (FTS_DC);
+ }
+ return (FTS_D);
+ }
+ if (S_ISLNK(sbp->st_mode))
+ return (FTS_SL);
+ if (S_ISREG(sbp->st_mode))
+ return (FTS_F);
+ return (FTS_DEFAULT);
+}
+
+static FTSENT *
+internal_function
+fts_sort(FTS *sp, FTSENT *head, register int nitems)
+{
+ register FTSENT **ap, *p;
+
+ /*
+ * Construct an array of pointers to the structures and call qsort(3).
+ * Reassemble the array in the order returned by qsort. If unable to
+ * sort for memory reasons, return the directory entries in their
+ * current order. Allocate enough space for the current needs plus
+ * 40 so don't realloc one entry at a time.
+ */
+ if (nitems > sp->fts_nitems) {
+ struct _ftsent **a;
+
+ sp->fts_nitems = nitems + 40;
+ if ((a = realloc(sp->fts_array,
+ (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) {
+ free(sp->fts_array);
+ sp->fts_array = NULL;
+ sp->fts_nitems = 0;
+ return (head);
+ }
+ sp->fts_array = a;
+ }
+ for (ap = sp->fts_array, p = head; p; p = p->fts_link)
+ *ap++ = p;
+ qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
+ for (head = *(ap = sp->fts_array); --nitems; ++ap)
+ ap[0]->fts_link = ap[1];
+ ap[0]->fts_link = NULL;
+ return (head);
+}
+
+static FTSENT *
+internal_function
+fts_alloc(FTS *sp, const char *name, size_t namelen)
+{
+ register FTSENT *p;
+ size_t len;
+
+ /*
+ * The file name is a variable length array and no stat structure is
+ * necessary if the user has set the nostat bit. Allocate the FTSENT
+ * structure, the file name and the stat structure in one chunk, but
+ * be careful that the stat structure is reasonably aligned. Since the
+ * fts_name field is declared to be of size 1, the fts_name pointer is
+ * namelen + 2 before the first possible address of the stat structure.
+ */
+ len = sizeof(FTSENT) + namelen;
+ if (!ISSET(FTS_NOSTAT))
+ len += sizeof(struct stat) + ALIGNBYTES;
+ if ((p = malloc(len)) == NULL)
+ return (NULL);
+
+ /* Copy the name and guarantee NUL termination. */
+ memmove(p->fts_name, name, namelen);
+ p->fts_name[namelen] = '\0';
+
+ if (!ISSET(FTS_NOSTAT))
+ p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
+ p->fts_namelen = namelen;
+ p->fts_path = sp->fts_path;
+ p->fts_errno = 0;
+ p->fts_flags = 0;
+ p->fts_instr = FTS_NOINSTR;
+ p->fts_number = 0;
+ p->fts_pointer = NULL;
+ return (p);
+}
+
+static void
+internal_function
+fts_lfree(register FTSENT *head)
+{
+ register FTSENT *p;
+
+ /* Free a linked list of structures. */
+ while ((p = head)) {
+ head = head->fts_link;
+ free(p);
+ }
+}
+
+/*
+ * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
+ * Most systems will allow creation of paths much longer than MAXPATHLEN, even
+ * though the kernel won't resolve them. Add the size (not just what's needed)
+ * plus 256 bytes so don't realloc the path 2 bytes at a time.
+ */
+static int
+internal_function
+fts_palloc(FTS *sp, size_t more)
+{
+ char *p;
+
+ sp->fts_pathlen += more + 256;
+ /*
+ * Check for possible wraparound. In an FTS, fts_pathlen is
+ * a signed int but in an FTSENT it is an unsigned short.
+ * We limit fts_pathlen to USHRT_MAX to be safe in both cases.
+ */
+ if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) {
+ free(sp->fts_path);
+ sp->fts_path = NULL;
+ __set_errno (ENAMETOOLONG);
+ return (1);
+ }
+ p = realloc(sp->fts_path, sp->fts_pathlen);
+ if (p == NULL) {
+ free(sp->fts_path);
+ sp->fts_path = NULL;
+ return 1;
+ }
+ sp->fts_path = p;
+ return 0;
+}
+
+/*
+ * When the path is realloc'd, have to fix all of the pointers in structures
+ * already returned.
+ */
+static void
+internal_function
+fts_padjust(FTS *sp, FTSENT *head)
+{
+ FTSENT *p;
+ char *addr = sp->fts_path;
+
+#define ADJUST(p) do { \
+ if ((p)->fts_accpath != (p)->fts_name) { \
+ (p)->fts_accpath = \
+ (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
+ } \
+ (p)->fts_path = addr; \
+} while (0)
+ /* Adjust the current set of children. */
+ for (p = sp->fts_child; p; p = p->fts_link)
+ ADJUST(p);
+
+ /* Adjust the rest of the tree, including the current level. */
+ for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
+ ADJUST(p);
+ p = p->fts_link ? p->fts_link : p->fts_parent;
+ }
+}
+
+static size_t
+internal_function
+fts_maxarglen(char * const *argv)
+{
+ size_t len, max;
+
+ for (max = 0; *argv; ++argv)
+ if ((len = strlen(*argv)) > max)
+ max = len;
+ return (max + 1);
+}
+
+/*
+ * Change to dir specified by fd or p->fts_accpath without getting
+ * tricked by someone changing the world out from underneath us.
+ * Assumes p->fts_dev and p->fts_ino are filled in.
+ */
+static int
+internal_function
+fts_safe_changedir(FTS *sp, FTSENT *p, int fd, const char *path)
+{
+ int ret, oerrno, newfd;
+ struct stat64 sb;
+
+ newfd = fd;
+ if (ISSET(FTS_NOCHDIR))
+ return (0);
+ if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0)
+ return (-1);
+ if (fstat64(newfd, &sb)) {
+ ret = -1;
+ goto bail;
+ }
+ if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
+ __set_errno (ENOENT); /* disinformation */
+ ret = -1;
+ goto bail;
+ }
+ ret = fchdir(newfd);
+bail:
+ oerrno = errno;
+ if (fd < 0)
+ (void)close(newfd);
+ __set_errno (oerrno);
+ return (ret);
+}
diff --git a/libc/misc/ftw/Makefile.in b/libc/misc/ftw/Makefile.in
index 501b9084d..084a73009 100644
--- a/libc/misc/ftw/Makefile.in
+++ b/libc/misc/ftw/Makefile.in
@@ -1,24 +1,24 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := ftw.c
-ifeq ($(UCLIBC_HAS_LFS),y)
-CSRC += ftw64.c
-endif
+subdirs += libc/misc/ftw
+
+CSRC-y := ftw.c
+CSRC-$(UCLIBC_HAS_LFS) += ftw64.c
MISC_FTW_DIR := $(top_srcdir)libc/misc/ftw
MISC_FTW_OUT := $(top_builddir)libc/misc/ftw
-MISC_FTW_SRC := $(patsubst %.c,$(MISC_FTW_DIR)/%.c,$(CSRC))
-MISC_FTW_OBJ := $(patsubst %.c,$(MISC_FTW_OUT)/%.o,$(CSRC))
+MISC_FTW_SRC := $(patsubst %.c,$(MISC_FTW_DIR)/%.c,$(CSRC-y))
+MISC_FTW_OBJ := $(patsubst %.c,$(MISC_FTW_OUT)/%.o,$(CSRC-y))
-libc-$(UCLIBC_HAS_FTW) += $(MISC_FTW_OBJ)
+libc-$(findstring y,$(UCLIBC_HAS_FTW)$(UCLIBC_HAS_NFTW)) += $(MISC_FTW_OBJ)
-objclean-y += misc_ftw_objclean
+objclean-y += CLEAN_libc/misc/ftw
-misc_ftw_objclean:
- $(RM) $(MISC_FTW_OUT)/*.{o,os}
+CLEAN_libc/misc/ftw:
+ $(do_rm) $(addprefix $(MISC_FTW_OUT)/*., o os)
diff --git a/libc/misc/ftw/ftw.c b/libc/misc/ftw/ftw.c
index c136f1e8d..05ea0fa66 100644
--- a/libc/misc/ftw/ftw.c
+++ b/libc/misc/ftw/ftw.c
@@ -14,15 +14,16 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <features.h>
+/* need errno.h before undefining _LIBC */
+#include <errno.h>
#ifdef __UCLIBC__
#undef _LIBC
#define HAVE_DIRENT_H 1
@@ -32,6 +33,7 @@
#endif
#if __GNUC__
+# undef alloca
# define alloca __builtin_alloca
#else
# if HAVE_ALLOCA_H
@@ -67,7 +69,6 @@ char *alloca ();
# endif
#endif
-#include <errno.h>
#include <ftw.h>
#include <limits.h>
#include <search.h>
@@ -77,39 +78,13 @@ char *alloca ();
#if HAVE_SYS_PARAM_H || defined _LIBC
# include <sys/param.h>
#endif
-#ifdef _LIBC
-# include <include/sys/stat.h>
-#else
-# include <sys/stat.h>
-#endif
+#include <sys/stat.h>
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(strchr) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-libc_hidden_proto(dirfd)
-libc_hidden_proto(tsearch)
-libc_hidden_proto(tfind)
-libc_hidden_proto(tdestroy)
-libc_hidden_proto(getcwd)
-libc_hidden_proto(chdir)
-libc_hidden_proto(fchdir)
-/* Experimentally off - libc_hidden_proto(mempcpy) */
-libc_hidden_proto(opendir)
-#ifdef __UCLIBC_HAS_LFS__
-libc_hidden_proto(readdir64)
-libc_hidden_proto(lstat64)
-libc_hidden_proto(stat64)
-#endif
-libc_hidden_proto(closedir)
-/* Experimentally off - libc_hidden_proto(stpcpy) */
-libc_hidden_proto(lstat)
-libc_hidden_proto(stat)
-
-#if ! _LIBC && !HAVE_DECL_STPCPY && !defined stpcpy
+#if !defined _LIBC && !HAVE_DECL_STPCPY && !defined stpcpy
char *stpcpy ();
#endif
-#if ! _LIBC && ! defined HAVE_MEMPCPY && ! defined mempcpy
+#if !defined _LIBC && ! defined HAVE_MEMPCPY && ! defined mempcpy
/* Be CAREFUL that there are no side effects in N. */
# define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
#endif
@@ -162,7 +137,7 @@ extern char *xgetcwd (void);
/* Arrange to make lstat calls go through the wrapper function
on systems with an lstat function that does not dereference symlinks
that are specified with a trailing slash. */
-#if ! _LIBC && ! LSTAT_FOLLOWS_SLASHED_SYMLINK && !defined __UCLIBC__
+#if !defined _LIBC && !defined LSTAT_FOLLOWS_SLASHED_SYMLINK && !defined __UCLIBC__
int rpl_lstat (const char *, struct stat *);
# undef lstat
# define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
@@ -774,13 +749,15 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors,
/* Entry points. */
-
+#ifdef __UCLIBC_HAS_FTW__
int
FTW_NAME (const char *path, FTW_FUNC_T func, int descriptors)
{
return ftw_startup (path, 0, func, descriptors, 0);
}
+#endif
+#ifdef __UCLIBC_HAS_NFTW__
#ifndef _LIBC
int
NFTW_NAME (const char *path, NFTW_FUNC_T func, int descriptors, int flags)
@@ -824,3 +801,4 @@ NFTW_OLD_NAME (const char *path, NFTW_FUNC_T func, int descriptors, int flags)
compat_symbol (libc, NFTW_OLD_NAME, NFTW_NAME, GLIBC_2_1);
#endif
#endif
+#endif
diff --git a/libc/misc/ftw/ftw64.c b/libc/misc/ftw/ftw64.c
index de2fe22d1..c07b71091 100644
--- a/libc/misc/ftw/ftw64.c
+++ b/libc/misc/ftw/ftw64.c
@@ -14,9 +14,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#define FTW_NAME ftw64
#define NFTW_NAME nftw64
diff --git a/libc/misc/glob/Makefile.in b/libc/misc/glob/Makefile.in
index 93367f41b..c89d2b08d 100644
--- a/libc/misc/glob/Makefile.in
+++ b/libc/misc/glob/Makefile.in
@@ -1,31 +1,25 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-ifeq ($(UCLIBC_HAS_GNU_GLOB),y)
-CSRC := glob.c
-ifeq ($(UCLIBC_HAS_LFS),y)
-CSRC += glob64.c
-endif
-else
-CSRC := glob-susv3.c
-ifeq ($(UCLIBC_HAS_LFS),y)
-CSRC += glob64-susv3.c
-endif
-endif
+subdirs += libc/misc/glob
+
+VARIANT := $(if $(UCLIBC_HAS_GNU_GLOB),,-susv3)
+CSRC-y := glob$(VARIANT).c
+CSRC-$(UCLIBC_HAS_LFS) += glob64$(VARIANT).c
MISC_GLOB_DIR := $(top_srcdir)libc/misc/glob
MISC_GLOB_OUT := $(top_builddir)libc/misc/glob
-MISC_GLOB_SRC := $(patsubst %.c,$(MISC_GLOB_DIR)/%.c,$(CSRC))
-MISC_GLOB_OBJ := $(patsubst %.c,$(MISC_GLOB_OUT)/%.o,$(CSRC))
+MISC_GLOB_SRC := $(patsubst %.c,$(MISC_GLOB_DIR)/%.c,$(CSRC-y))
+MISC_GLOB_OBJ := $(patsubst %.c,$(MISC_GLOB_OUT)/%.o,$(CSRC-y))
libc-$(UCLIBC_HAS_GLOB) += $(MISC_GLOB_OBJ)
-objclean-y += misc_glob_objclean
+objclean-y += CLEAN_libc/misc/glob
-misc_glob_objclean:
- $(RM) $(MISC_GLOB_OUT)/*.{o,os}
+CLEAN_libc/misc/glob:
+ $(do_rm) $(addprefix $(MISC_GLOB_OUT)/*., o os)
diff --git a/libc/misc/glob/glob-susv3.c b/libc/misc/glob/glob-susv3.c
index 00963c36e..59b4d8e5f 100644
--- a/libc/misc/glob/glob-susv3.c
+++ b/libc/misc/glob/glob-susv3.c
@@ -23,16 +23,6 @@
#include <unistd.h>
#include <stdio.h>
-/* Experimentally off - libc_hidden_proto(memcpy) */
-/* Experimentally off - libc_hidden_proto(strcat) */
-/* Experimentally off - libc_hidden_proto(strchr) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strcpy) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-libc_hidden_proto(opendir)
-libc_hidden_proto(closedir)
-libc_hidden_proto(qsort)
-libc_hidden_proto(fnmatch)
struct match
{
@@ -53,12 +43,8 @@ extern int __glob_match_in_dir(const char *d, const char *p, int flags, int (*er
# define stat stat64
# define readdir_r readdir64_r
# define dirent dirent64
-libc_hidden_proto(readdir64_r)
-libc_hidden_proto(stat64)
# define struct_stat struct stat64
#else
-libc_hidden_proto(readdir_r)
-libc_hidden_proto(stat)
# define struct_stat struct stat
#endif
@@ -197,7 +183,8 @@ int __glob_match_in_dir(const char *d, const char *p, int flags, int (*errfunc)(
# ifndef BUILD_GLOB64
static
# endif
-int __glob_ignore_err(const char *path, int err)
+int __glob_ignore_err(const char * path attribute_unused,
+ int err attribute_unused)
{
return 0;
}
@@ -223,11 +210,6 @@ int __glob_sort(const void *a, const void *b)
}
#endif /* !__GLOB64 */
-#ifdef __GLOB64
-libc_hidden_proto(glob64)
-#else
-libc_hidden_proto(glob)
-#endif
int glob(const char *pat, int flags, int (*errfunc)(const char *path, int err), glob_t *g)
{
const char *p=pat, *d;
@@ -301,11 +283,6 @@ libc_hidden_def(glob64)
libc_hidden_def(glob)
#endif
-#ifdef __GLOB64
-libc_hidden_proto(globfree64)
-#else
-libc_hidden_proto(globfree)
-#endif
void globfree(glob_t *g)
{
size_t i;
diff --git a/libc/misc/glob/glob.c b/libc/misc/glob/glob.c
index 6ccbda4d7..923c03538 100644
--- a/libc/misc/glob/glob.c
+++ b/libc/misc/glob/glob.c
@@ -12,9 +12,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#undef ENABLE_GLOB_BRACE_EXPANSION
#undef ENABLE_GLOB_TILDE_EXPANSION
@@ -31,24 +30,10 @@
#include <fnmatch.h>
#include <glob.h>
-libc_hidden_proto(closedir)
-libc_hidden_proto(fnmatch)
-/* Experimentally off - libc_hidden_proto(memcpy) */
-/* Experimentally off - libc_hidden_proto(mempcpy) */
-libc_hidden_proto(opendir)
-libc_hidden_proto(qsort)
-libc_hidden_proto(readdir)
-/* Experimentally off - libc_hidden_proto(strchr) */
-/* Experimentally off - libc_hidden_proto(strcoll) */
-/* Experimentally off - libc_hidden_proto(strcpy) */
-/* Experimentally off - libc_hidden_proto(strdup) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-/* Experimentally off - libc_hidden_proto(strrchr) */
#ifdef ENABLE_GLOB_TILDE_EXPANSION
#include <pwd.h>
-libc_hidden_proto(getpwnam_r)
#endif
#ifdef COMPILE_GLOB64
@@ -62,19 +47,15 @@ libc_hidden_proto(getpwnam_r)
#define glob_t glob64_t
#define glob(pattern, flags, errfunc, pglob) glob64 (pattern, flags, errfunc, pglob)
#define globfree(pglob) globfree64 (pglob)
-libc_hidden_proto(stat64)
-libc_hidden_proto(readdir64)
#else
#define __readdir readdir
#ifdef __UCLIBC_HAS_LFS__
#define __readdir64 readdir64
-libc_hidden_proto(readdir64)
#else
#define __readdir64 readdir
#endif
#define struct_stat64 struct stat
#define __stat64(fname, buf) stat (fname, buf)
-libc_hidden_proto(stat)
#endif
@@ -132,7 +113,6 @@ extern int __prefix_array (const char *dirname, char **array, size_t n) attribut
extern const char *__next_brace_sub (const char *cp, int flags) attribute_hidden;
#endif
-libc_hidden_proto(glob_pattern_p)
#ifndef COMPILE_GLOB64
/* Return nonzero if PATTERN contains any metacharacters.
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
@@ -488,13 +468,6 @@ static int glob_in_dir (const char *pattern, const char *directory, int flags,
return GLOB_NOSPACE;
}
-#ifdef COMPILE_GLOB64
-libc_hidden_proto(glob64)
-libc_hidden_proto(globfree64)
-#else
-libc_hidden_proto(glob)
-libc_hidden_proto(globfree)
-#endif
/* Do glob searching for PATTERN, placing results in PGLOB.
The bits defined above may be set in FLAGS.
If a directory cannot be opened or read and ERRFUNC is not nil,
diff --git a/libc/misc/gnu/Makefile.in b/libc/misc/gnu/Makefile.in
index d64a9eed3..99bf81442 100644
--- a/libc/misc/gnu/Makefile.in
+++ b/libc/misc/gnu/Makefile.in
@@ -1,21 +1,24 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := obstack.c
+subdirs += libc/misc/gnu
+
+CSRC-y :=
+CSRC-$(UCLIBC_HAS_OBSTACK) := obstack.c obprintf.c
MISC_GNU_DIR := $(top_srcdir)libc/misc/gnu
MISC_GNU_OUT := $(top_builddir)libc/misc/gnu
-MISC_GNU_SRC := $(MISC_GNU_DIR)/obstack.c
-MISC_GNU_OBJ := $(MISC_GNU_OUT)/obstack.o
+MISC_GNU_SRC := $(patsubst %.c,$(MISC_GNU_DIR)/%.c,$(CSRC-y))
+MISC_GNU_OBJ := $(patsubst %.c,$(MISC_GNU_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_GNU_OBJ)
-objclean-y += misc_gnu_objclean
+objclean-y += CLEAN_libc/misc/gnu
-misc_gnu_objclean:
- $(RM) $(MISC_GNU_OUT)/*.{o,os}
+CLEAN_libc/misc/gnu:
+ $(do_rm) $(addprefix $(MISC_GNU_OUT)/*., o os)
diff --git a/libc/misc/gnu/obprintf.c b/libc/misc/gnu/obprintf.c
new file mode 100644
index 000000000..3f8eda832
--- /dev/null
+++ b/libc/misc/gnu/obprintf.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2013 Gentoo Foundation
+ * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <obstack.h>
+
+int
+obstack_vprintf (struct obstack *obstack, const char *format, va_list args)
+{
+ int n;
+ char *s;
+ n = vasprintf(&s, format, args);
+ obstack_grow(obstack, s, n);
+ return n;
+}
+libc_hidden_def(obstack_vprintf)
+
+int
+obstack_printf (struct obstack *obstack, const char *format, ...)
+{
+ int n;
+ va_list ap;
+ va_start (ap, format);
+ n = obstack_vprintf (obstack, format, ap);
+ va_end (ap);
+ return n;
+}
diff --git a/libc/misc/gnu/obstack.c b/libc/misc/gnu/obstack.c
index 246d164cd..38cfd83de 100644
--- a/libc/misc/gnu/obstack.c
+++ b/libc/misc/gnu/obstack.c
@@ -1,7 +1,7 @@
/* obstack.c - subroutines used implicitly by object stack macros
- Copyright (C) 1988-1994,96,97,98,99,2000,2001 Free Software Foundation, Inc.
- This file is part of the GNU C Library. Its master source is NOT part of
- the C library, however. The master source lives in /gd/gnu/lib.
+ Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 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
@@ -14,20 +14,25 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
-/* Make uClibc lie about being glibc. */
-#define __FORCE_GLIBC 1
-
-#include <locale.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
-#include <obstack.h>
+#ifdef _LIBC
+# include <obstack.h>
+#ifndef __UCLIBC__
+# include <shlib-compat.h>
+#else
+# define HAVE_INTTYPES_H 1
+# define HAVE_STDINT_H 1
+#endif
+#else
+# include "obstack.h"
+#endif
/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
incremented whenever callers compiled using an old obstack.h can no
@@ -51,28 +56,38 @@
# endif
#endif
-#if (defined _LIBC && defined USE_IN_LIBIO) || defined __UCLIBC_HAS_WCHAR__
-# include <wchar.h>
-#endif
+#include <stddef.h>
#ifndef ELIDE_CODE
-# if defined __STDC__ && __STDC__
-# define POINTER void *
-# else
-# define POINTER char *
+# if HAVE_INTTYPES_H
+# include <inttypes.h>
+# endif
+# if HAVE_STDINT_H || defined _LIBC
+# include <stdint.h>
# endif
/* Determine default alignment. */
-struct fooalign {char x; double d;};
-# define DEFAULT_ALIGNMENT \
- ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
+union fooround
+{
+ uintmax_t i;
+ long double d;
+ void *p;
+};
+struct fooalign
+{
+ char c;
+ union fooround u;
+};
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
But in fact it might be less smart and round addresses to as much as
DEFAULT_ROUNDING. So we prepare for it to do that. */
-union fooround {long x; double d;};
-# define DEFAULT_ROUNDING (sizeof (union fooround))
+enum
+ {
+ DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
+ DEFAULT_ROUNDING = sizeof (union fooround)
+ };
/* When we copy a long block of data, this is the unit to do it with.
On some machines, copying successive ints does not work;
@@ -89,36 +104,29 @@ union fooround {long x; double d;};
abort gracefully or use longjump - but shouldn't return. This
variable by default points to the internal function
`print_and_abort'. */
-# if defined __STDC__ && __STDC__
static void print_and_abort (void);
-void (*obstack_alloc_failed_handler) (void) = print_and_abort;
-# else
-static void print_and_abort ();
-void (*obstack_alloc_failed_handler) () = print_and_abort;
-# endif
-
+static void (*__obstack_alloc_failed_handler) (void) = print_and_abort;
+strong_alias(__obstack_alloc_failed_handler,obstack_alloc_failed_handler)
/* Exit value used when `print_and_abort' is used. */
-# if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-# ifndef EXIT_FAILURE
-# define EXIT_FAILURE 1
+# include <stdlib.h>
+# ifdef _LIBC
+static int __obstack_exit_failure = EXIT_FAILURE;
+strong_alias(__obstack_exit_failure,obstack_exit_failure)
+# else
+# include "exitfail.h"
+# define __obstack_exit_failure exit_failure
# endif
-libc_hidden_proto(fprintf)
-libc_hidden_proto(abort)
-libc_hidden_proto(exit)
-#ifdef __UCLIBC_HAS_WCHAR__
-libc_hidden_proto(fwprintf)
-#endif
-
-int obstack_exit_failure = EXIT_FAILURE;
-
-/* The non-GNU-C macros copy the obstack into this global variable
- to avoid multiple evaluation. */
-
-struct obstack *_obstack;
+# if 0
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+/* A looong time ago (before 1994, anyway; we're not sure) this global variable
+ was used by non-GNU-C macros to avoid multiple evaluation. The GNU C
+ library still exports it because somebody might use it. */
+struct obstack *_obstack_compat;
+compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
+# endif
+# endif
/* Define a macro that either calls functions with the traditional malloc/free
calling interface, or calls functions with the mmalloc/mfree interface
@@ -126,33 +134,18 @@ struct obstack *_obstack;
For free, do not use ?:, since some compilers, like the MIPS compilers,
do not allow (expr) ? void : void. */
-# if defined __STDC__ && __STDC__
-# define CALL_CHUNKFUN(h, size) \
+# define CALL_CHUNKFUN(h, size) \
(((h) -> use_extra_arg) \
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
: (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
-# define CALL_FREEFUN(h, old_chunk) \
+# define CALL_FREEFUN(h, old_chunk) \
do { \
if ((h) -> use_extra_arg) \
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
else \
(*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
} while (0)
-# else
-# define CALL_CHUNKFUN(h, size) \
- (((h) -> use_extra_arg) \
- ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
- : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
-
-# define CALL_FREEFUN(h, old_chunk) \
- do { \
- if ((h) -> use_extra_arg) \
- (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
- else \
- (*(void (*) ()) (h)->freefun) ((old_chunk)); \
- } while (0)
-# endif
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
@@ -164,23 +157,15 @@ struct obstack *_obstack;
allocation fails. */
int
-_obstack_begin (
- struct obstack *h,
- int size,
- int alignment,
-# if defined __STDC__ && __STDC__
- POINTER (*chunkfun) (long),
- void (*freefun) (void *)
-# else
- POINTER (*chunkfun) (),
- void (*freefun) ()
-# endif
- )
+_obstack_begin (struct obstack *h,
+ int size, int alignment,
+ void *(*chunkfun) (long),
+ void (*freefun) (void *))
{
register struct _obstack_chunk *chunk; /* points to new chunk */
if (alignment == 0)
- alignment = (int) DEFAULT_ALIGNMENT;
+ alignment = DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block. */
{
@@ -198,21 +183,17 @@ _obstack_begin (
size = 4096 - extra;
}
-# if defined __STDC__ && __STDC__
h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
-# else
- h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
- h->freefun = freefun;
-# endif
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->use_extra_arg = 0;
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
if (!chunk)
- (*obstack_alloc_failed_handler) ();
- h->next_free = h->object_base = chunk->contents;
+ (*__obstack_alloc_failed_handler) ();
+ h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
+ alignment - 1);
h->chunk_limit = chunk->limit
= (char *) chunk + h->chunk_size;
chunk->prev = 0;
@@ -223,23 +204,15 @@ _obstack_begin (
}
int
-_obstack_begin_1 (
- struct obstack *h,
- int size,
- int alignment,
-# if defined __STDC__ && __STDC__
- POINTER (*chunkfun) (POINTER, long),
- void (*freefun) (POINTER, POINTER),
-# else
- POINTER (*chunkfun) (),
- void (*freefun) (),
-# endif
- POINTER arg)
+_obstack_begin_1 (struct obstack *h, int size, int alignment,
+ void *(*chunkfun) (void *, long),
+ void (*freefun) (void *, void *),
+ void *arg)
{
register struct _obstack_chunk *chunk; /* points to new chunk */
if (alignment == 0)
- alignment = (int) DEFAULT_ALIGNMENT;
+ alignment = DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block. */
{
@@ -257,13 +230,8 @@ _obstack_begin_1 (
size = 4096 - extra;
}
-# if defined __STDC__ && __STDC__
h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
-# else
- h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
- h->freefun = freefun;
-# endif
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->extra_arg = arg;
@@ -271,8 +239,9 @@ _obstack_begin_1 (
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
if (!chunk)
- (*obstack_alloc_failed_handler) ();
- h->next_free = h->object_base = chunk->contents;
+ (*__obstack_alloc_failed_handler) ();
+ h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
+ alignment - 1);
h->chunk_limit = chunk->limit
= (char *) chunk + h->chunk_size;
chunk->prev = 0;
@@ -289,9 +258,7 @@ _obstack_begin_1 (
to the beginning of the new one. */
void
-_obstack_newchunk (
- struct obstack *h,
- int length)
+_obstack_newchunk (struct obstack *h, int length)
{
register struct _obstack_chunk *old_chunk = h->chunk;
register struct _obstack_chunk *new_chunk;
@@ -309,15 +276,14 @@ _obstack_newchunk (
/* Allocate and initialize the new chunk. */
new_chunk = CALL_CHUNKFUN (h, new_size);
if (!new_chunk)
- (*obstack_alloc_failed_handler) ();
+ (*__obstack_alloc_failed_handler) ();
h->chunk = new_chunk;
new_chunk->prev = old_chunk;
new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
/* Compute an aligned object_base in the new chunk */
object_base =
- __INT_TO_PTR ((__PTR_TO_INT (new_chunk->contents) + h->alignment_mask)
- & ~ (h->alignment_mask));
+ __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
/* Move the existing object to the new chunk.
Word at a time is fast and is safe if the object
@@ -342,7 +308,10 @@ _obstack_newchunk (
/* If the object just copied was the only data in OLD_CHUNK,
free that chunk and remove it from the chain.
But not if that chunk might contain an empty object. */
- if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
+ if (! h->maybe_empty_object
+ && (h->object_base
+ == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
+ h->alignment_mask)))
{
new_chunk->prev = old_chunk->prev;
CALL_FREEFUN (h, old_chunk);
@@ -353,21 +322,18 @@ _obstack_newchunk (
/* The new chunk certainly contains no empty object yet. */
h->maybe_empty_object = 0;
}
+libc_hidden_def(_obstack_newchunk)
/* Return nonzero if object OBJ has been allocated from obstack H.
This is here for debugging.
If you use it in a program, you are probably losing. */
-# if defined __STDC__ && __STDC__
/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
obstack.h because it is just for debugging. */
-int _obstack_allocated_p (struct obstack *h, POINTER obj);
-# endif
+int _obstack_allocated_p (struct obstack *h, void *obj);
int
-_obstack_allocated_p (
- struct obstack *h,
- POINTER obj)
+_obstack_allocated_p (struct obstack *h, void *obj)
{
register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk *plp; /* point to previous chunk if any */
@@ -376,7 +342,7 @@ _obstack_allocated_p (
/* We use >= rather than > since the object cannot be exactly at
the beginning of the chunk but might be an empty object exactly
at the end of an adjacent chunk. */
- while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
{
plp = lp->prev;
lp = plp;
@@ -389,13 +355,8 @@ _obstack_allocated_p (
# undef obstack_free
-/* This function has two names with identical definitions.
- This is the first one, called from non-ANSI code. */
-
void
-_obstack_free (
- struct obstack *h,
- POINTER obj)
+obstack_free (struct obstack *h, void *obj)
{
register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk *plp; /* point to previous chunk if any */
@@ -404,7 +365,7 @@ _obstack_free (
/* We use >= because there cannot be an object at the beginning of a chunk.
But there can be an empty object at that address
at the end of another chunk. */
- while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
{
plp = lp->prev;
CALL_FREEFUN (h, lp);
@@ -424,43 +385,14 @@ _obstack_free (
abort ();
}
-/* This function is used from ANSI code. */
-
-void
-obstack_free (
- struct obstack *h,
- POINTER obj)
-{
- register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
- register struct _obstack_chunk *plp; /* point to previous chunk if any */
-
- lp = h->chunk;
- /* We use >= because there cannot be an object at the beginning of a chunk.
- But there can be an empty object at that address
- at the end of another chunk. */
- while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
- {
- plp = lp->prev;
- CALL_FREEFUN (h, lp);
- lp = plp;
- /* If we switch chunks, we can't tell whether the new current
- chunk contains an empty object, so assume that it may. */
- h->maybe_empty_object = 1;
- }
- if (lp)
- {
- h->object_base = h->next_free = (char *) (obj);
- h->chunk_limit = lp->limit;
- h->chunk = lp;
- }
- else if (obj != 0)
- /* obj is not in any of the chunks! */
- abort ();
-}
+# if 0
+/* Older versions of libc used a function _obstack_free intended to be
+ called by non-GCC compilers. */
+strong_alias (obstack_free, _obstack_free)
+# endif
int
-_obstack_memory_used (
- struct obstack *h)
+_obstack_memory_used (struct obstack *h)
{
register struct _obstack_chunk* lp;
register int nbytes = 0;
@@ -473,20 +405,24 @@ _obstack_memory_used (
}
/* Define the error handler. */
+# ifdef _LIBC
+# include <libintl.h>
+# else
+# include "gettext.h"
+# endif
# ifndef _
-/* # if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC */
-# ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
-# include <libintl.h>
-# ifndef _
-# define _(Str) __dcgettext (NULL, Str, LC_MESSAGES)
-# endif
-# else
-# define _(Str) (Str)
-# endif
+# define _(msgid) gettext (msgid)
# endif
-# if defined _LIBC && defined USE_IN_LIBIO
+
+# if defined _LIBC && !defined __UCLIBC__
# include <libio/iolibio.h>
-# define fputs(s, f) _IO_fputs (s, f)
+# endif
+
+# ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+# define __attribute__(Spec) /* empty */
+# endif
# endif
static void
@@ -498,135 +434,12 @@ print_and_abort (void)
happen because the "memory exhausted" message appears in other places
like this and the translation should be reused instead of creating
a very similar string which requires a separate translation. */
-# if defined _LIBC && defined USE_IN_LIBIO
- if (_IO_fwide (stderr, 0) > 0)
- fwprintf (stderr, L"%s\n", _("memory exhausted"));
- else
+# if defined _LIBC && !defined __UCLIBC__
+ (void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
+# else
+ fprintf (stderr, "%s\n", _("memory exhausted"));
# endif
- fprintf (stderr, "%s\n", _("memory exhausted"));
- exit (obstack_exit_failure);
-}
-
-# if 0
-/* These are now turned off because the applications do not use it
- and it uses bcopy via obstack_grow, which causes trouble on sysV. */
-
-/* Now define the functional versions of the obstack macros.
- Define them to simply use the corresponding macros to do the job. */
-
-# if defined __STDC__ && __STDC__
-/* These function definitions do not work with non-ANSI preprocessors;
- they won't pass through the macro names in parentheses. */
-
-/* The function names appear in parentheses in order to prevent
- the macro-definitions of the names from being expanded there. */
-
-POINTER (obstack_base) (obstack)
- struct obstack *obstack;
-{
- return obstack_base (obstack);
-}
-
-POINTER (obstack_next_free) (obstack)
- struct obstack *obstack;
-{
- return obstack_next_free (obstack);
-}
-
-int (obstack_object_size) (obstack)
- struct obstack *obstack;
-{
- return obstack_object_size (obstack);
-}
-
-int (obstack_room) (obstack)
- struct obstack *obstack;
-{
- return obstack_room (obstack);
-}
-
-int (obstack_make_room) (obstack, length)
- struct obstack *obstack;
- int length;
-{
- return obstack_make_room (obstack, length);
+ exit (__obstack_exit_failure);
}
-void (obstack_grow) (obstack, data, length)
- struct obstack *obstack;
- const POINTER data;
- int length;
-{
- obstack_grow (obstack, data, length);
-}
-
-void (obstack_grow0) (obstack, data, length)
- struct obstack *obstack;
- const POINTER data;
- int length;
-{
- obstack_grow0 (obstack, data, length);
-}
-
-void (obstack_1grow) (obstack, character)
- struct obstack *obstack;
- int character;
-{
- obstack_1grow (obstack, character);
-}
-
-void (obstack_blank) (obstack, length)
- struct obstack *obstack;
- int length;
-{
- obstack_blank (obstack, length);
-}
-
-void (obstack_1grow_fast) (obstack, character)
- struct obstack *obstack;
- int character;
-{
- obstack_1grow_fast (obstack, character);
-}
-
-void (obstack_blank_fast) (obstack, length)
- struct obstack *obstack;
- int length;
-{
- obstack_blank_fast (obstack, length);
-}
-
-POINTER (obstack_finish) (obstack)
- struct obstack *obstack;
-{
- return obstack_finish (obstack);
-}
-
-POINTER (obstack_alloc) (obstack, length)
- struct obstack *obstack;
- int length;
-{
- return obstack_alloc (obstack, length);
-}
-
-POINTER (obstack_copy) (obstack, address, length)
- struct obstack *obstack;
- const POINTER address;
- int length;
-{
- return obstack_copy (obstack, address, length);
-}
-
-POINTER (obstack_copy0) (obstack, address, length)
- struct obstack *obstack;
- const POINTER address;
- int length;
-{
- return obstack_copy0 (obstack, address, length);
-}
-
-# endif /* __STDC__ */
-
-# endif /* 0 */
-
#endif /* !ELIDE_CODE */
diff --git a/libc/misc/internals/Makefile.in b/libc/misc/internals/Makefile.in
index 1356745d6..ae094ee23 100644
--- a/libc/misc/internals/Makefile.in
+++ b/libc/misc/internals/Makefile.in
@@ -1,19 +1,23 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CFLAGS-__uClibc_main.c := $(SSP_DISABLE_FLAGS)
+subdirs += libc/misc/internals
-CSRC := tempname.c errno.c __errno_location.c __h_errno_location.c
+CSRC-y := tempname.c errno.c h_errno.c __errno_location.c __h_errno_location.c \
+ parse_config.c
MISC_INTERNALS_DIR := $(top_srcdir)libc/misc/internals
MISC_INTERNALS_OUT := $(top_builddir)libc/misc/internals
-MISC_INTERNALS_SRC := $(patsubst %.c,$(MISC_INTERNALS_DIR)/%.c,$(CSRC))
-MISC_INTERNALS_OBJ := $(patsubst %.c,$(MISC_INTERNALS_OUT)/%.o,$(CSRC))
+MISC_INTERNALS_SRC := $(patsubst %.c,$(MISC_INTERNALS_DIR)/%.c,$(CSRC-y))
+MISC_INTERNALS_OBJ := $(patsubst %.c,$(MISC_INTERNALS_OUT)/%.o,$(CSRC-y))
+
+CFLAGS-__uClibc_main.c := $(SSP_DISABLE_FLAGS)
+
libc-y += $(MISC_INTERNALS_OBJ)
ifneq ($(UCLIBC_FORMAT_SHARED_FLAT),y)
@@ -33,7 +37,7 @@ libc-shared-$(UCLIBC_FORMAT_SHARED_FLAT) += \
$(MISC_INTERNALS_OUT)/shared_flat_add_library.os
libc-nomulti-y += $(MISC_INTERNALS_OUT)/__uClibc_main.o
-objclean-y += misc_internals_objclean
+objclean-y += CLEAN_libc/misc/internals
-misc_internals_objclean:
- $(RM) $(MISC_INTERNALS_OUT)/*.{o,os,oS}
+CLEAN_libc/misc/internals:
+ $(do_rm) $(addprefix $(MISC_INTERNALS_OUT)/*., o os oS)
diff --git a/libc/misc/internals/__errno_location.c b/libc/misc/internals/__errno_location.c
index a44bf6062..6c359f933 100644
--- a/libc/misc/internals/__errno_location.c
+++ b/libc/misc/internals/__errno_location.c
@@ -4,14 +4,15 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#include "internal_errno.h"
+#include <features.h>
+#include <errno.h>
-/* psm: moved to bits/errno.h: libc_hidden_proto(__errno_location) */
-libc_hidden_proto(__errno_location)
-int * weak_const_function __errno_location (void)
+#ifndef __UCLIBC_HAS_TLS__
+# undef errno
+extern int errno;
+#endif
+
+int weak_const_function *__errno_location(void)
{
return &errno;
}
-#ifdef IS_IN_libc /* not really need, only to keep in sync w/ libc_hidden_proto */
-libc_hidden_weak(__errno_location)
-#endif
diff --git a/libc/misc/internals/__h_errno_location.c b/libc/misc/internals/__h_errno_location.c
index 2ac21774c..c510c8143 100644
--- a/libc/misc/internals/__h_errno_location.c
+++ b/libc/misc/internals/__h_errno_location.c
@@ -4,11 +4,15 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#include "internal_errno.h"
+#include <features.h>
+#include <netdb.h>
-libc_hidden_proto(__h_errno_location)
-int * weak_const_function __h_errno_location (void)
+#ifndef __UCLIBC_HAS_TLS__
+# undef h_errno
+extern int h_errno;
+#endif
+
+int weak_const_function *__h_errno_location(void)
{
return &h_errno;
}
-libc_hidden_weak(__h_errno_location)
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index 6c0dab7fe..632a2528e 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) Feb 2001 Manuel Novoa III
+ * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com>
+ * Copyright (C) 2001 by Manuel Novoa III <mjn3@uclibc.org>
* Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
*
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
@@ -13,7 +14,6 @@
* avoided in the static library case.
*/
-#define _ERRNO_H
#include <features.h>
#include <unistd.h>
#include <stdlib.h>
@@ -22,69 +22,119 @@
#include <link.h>
#include <bits/uClibc_page.h>
#include <paths.h>
-#include <asm/errno.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#ifndef __ARCH_HAS_NO_LDSO__
#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-
-libc_hidden_proto(exit)
-
-#ifdef __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__
-/* Experimentally off - libc_hidden_proto(strrchr) */
#endif
-#ifndef __ARCH_HAS_NO_LDSO__
-/* Experimentally off - libc_hidden_proto(memcpy) */
-libc_hidden_proto(getgid)
-libc_hidden_proto(getuid)
-libc_hidden_proto(getegid)
-libc_hidden_proto(geteuid)
-libc_hidden_proto(fstat)
-libc_hidden_proto(abort)
-
-extern __typeof(open) __libc_open;
-libc_hidden_proto(__libc_open)
-extern __typeof(fcntl) __libc_fcntl;
-libc_hidden_proto(__libc_fcntl)
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <pthread-functions.h>
+#include <not-cancel.h>
+#include <atomic.h>
+#include <tls.h>
+#endif
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+#endif
+#ifdef __UCLIBC_HAS_LOCALE__
+#include <locale.h>
#endif
+/* Are we in a secure process environment or are we dealing
+ * with setuid stuff? If we are dynamically linked, then we
+ * already have _dl_secure, otherwise we need to re-examine
+ * auxvt[] below.
+ */
+int _pe_secure = 0;
+libc_hidden_data_def(_pe_secure)
+
#ifndef SHARED
-void *__libc_stack_end=NULL;
+void *__libc_stack_end = NULL;
# ifdef __UCLIBC_HAS_SSP__
# include <dl-osinfo.h>
+static uintptr_t stack_chk_guard;
# ifndef THREAD_SET_STACK_GUARD
/* Only exported for architectures that don't store the stack guard canary
* in thread local area. */
-# include <stdint.h>
-uintptr_t stack_chk_guard;
/* for gcc-4.1 non-TLS */
uintptr_t __stack_chk_guard attribute_relro;
+# endif
/* for gcc-3.x + Etoh ssp */
-# ifdef __UCLIBC_HAS_SSP_COMPAT__
-# ifdef __HAVE_SHARED__
-strong_alias(__stack_chk_guard,__guard)
-# else
-uintptr_t __guard attribute_relro;
-# endif
-# endif
-# elif defined __UCLIBC_HAS_SSP_COMPAT__
+# ifdef __UCLIBC_HAS_SSP_COMPAT__
uintptr_t __guard attribute_relro;
# endif
# endif
+/*
+ * Needed to initialize _dl_phdr when statically linked
+ */
+
+void internal_function _dl_aux_init (ElfW(auxv_t) *av);
+
+#ifdef __UCLIBC_HAS_THREADS__
+/*
+ * uClibc internal locking requires that we have weak aliases
+ * for dummy functions in case libpthread.a is not linked in.
+ * This needs to be in compilation unit that is pulled always
+ * in or linker will disregard these weaks.
+ */
+
+static int __pthread_return_0 (pthread_mutex_t *unused) { return 0; }
+weak_alias (__pthread_return_0, __pthread_mutex_lock)
+weak_alias (__pthread_return_0, __pthread_mutex_trylock)
+weak_alias (__pthread_return_0, __pthread_mutex_unlock)
+
+int weak_function
+__pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
+{
+ return 0;
+}
+
+void weak_function
+_pthread_cleanup_push_defer(struct _pthread_cleanup_buffer *__buffer,
+ void (*__routine) (void *), void *__arg)
+{
+ __buffer->__routine = __routine;
+ __buffer->__arg = __arg;
+}
+
+void weak_function
+_pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *__buffer,
+ int __execute)
+{
+ if (__execute)
+ __buffer->__routine(__buffer->__arg);
+}
+#endif /* __UCLIBC_HAS_THREADS__ */
+
#endif /* !SHARED */
+/* Defeat compiler optimization which assumes function addresses are never NULL */
+static __always_inline int not_null_ptr(const void *p)
+{
+ const void *q;
+ __asm__ (""
+ : "=r" (q) /* output */
+ : "0" (p) /* input */
+ );
+ return q != 0;
+}
+
/*
* Prototypes.
*/
-extern void weak_function _stdio_init(void) attribute_hidden;
-extern int *weak_const_function __errno_location(void);
-extern int *weak_const_function __h_errno_location(void);
-#ifdef __UCLIBC_HAS_LOCALE__
-extern void weak_function _locale_init(void) attribute_hidden;
-#endif
#ifdef __UCLIBC_HAS_THREADS__
+#if !defined (__UCLIBC_HAS_THREADS_NATIVE__) || defined (SHARED)
extern void weak_function __pthread_initialize_minimal(void);
+#else
+extern void __pthread_initialize_minimal(void);
+#endif
+#endif
+
+#ifndef SHARED
+extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
#endif
/* If __UCLIBC_FORMAT_SHARED_FLAT__, all array initialisation and finalisation
@@ -103,25 +153,33 @@ extern void (*__fini_array_end []) (void) attribute_hidden;
# endif
#endif
-attribute_hidden const char *__uclibc_progname = "";
-#ifdef __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__
-const char *program_invocation_short_name = "";
-const char *program_invocation_name = "";
+#ifdef SHARED
+extern int _dl_secure;
+#endif
+extern size_t _dl_pagesize;
+
+const char *__uclibc_progname = "";
+#if !defined __UCLIBC_HAS___PROGNAME__ && defined __USE_GNU && defined __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__
+# define __progname program_invocation_short_name
+# define __progname_full program_invocation_name
#endif
-#ifdef __UCLIBC_HAS___PROGNAME__
-weak_alias (program_invocation_short_name, __progname)
-weak_alias (program_invocation_name, __progname_full)
+#if defined __UCLIBC_HAS___PROGNAME__ || (defined __USE_GNU && defined __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__)
+const char *__progname = "";
+/* psm: why have a visible __progname_full? */
+const char *__progname_full = "";
+# if defined __UCLIBC_HAS___PROGNAME__ && defined __USE_GNU && defined __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__
+weak_alias (__progname, program_invocation_short_name)
+weak_alias (__progname_full, program_invocation_name)
+# endif
#endif
/*
- * Declare the __environ global variable and create a strong alias environ.
- * Note: Apparently we must initialize __environ to ensure that the strong
- * environ symbol is also included.
+ * Declare the __environ global variable and create a weak alias environ.
+ * This must be initialized; we cannot have a weak alias into bss.
*/
char **__environ = 0;
weak_alias(__environ, environ)
-/* TODO: don't export __pagesize; we cant now because libpthread uses it */
size_t __pagesize = 0;
#ifndef O_NOFOLLOW
@@ -132,13 +190,13 @@ size_t __pagesize = 0;
static void __check_one_fd(int fd, int mode)
{
/* Check if the specified fd is already open */
- if (__libc_fcntl(fd, F_GETFD) == -1)
+ if (fcntl(fd, F_GETFD) == -1)
{
/* The descriptor is probably not open, so try to use /dev/null */
- int nullfd = __libc_open(_PATH_DEVNULL, mode);
+ int nullfd = open(_PATH_DEVNULL, mode);
/* /dev/null is major=1 minor=3. Make absolutely certain
* that is in fact the device that we have opened and not
- * some other wierd file... */
+ * some other wierd file... [removed in uclibc] */
if (nullfd!=fd)
{
abort();
@@ -146,6 +204,7 @@ static void __check_one_fd(int fd, int mode)
}
}
+#ifndef SHARED
static int __check_suid(void)
{
uid_t uid, euid;
@@ -162,6 +221,7 @@ static int __check_suid(void)
return 0; /* we are not suid */
}
#endif
+#endif
/* __uClibc_init completely initialize uClibc so it is ready to use.
*
@@ -176,26 +236,32 @@ static int __check_suid(void)
* __uClibc_main.
*/
-extern void __uClibc_init(void);
-libc_hidden_proto(__uClibc_init)
+extern void __uClibc_init(void) attribute_hidden;
void __uClibc_init(void)
{
- static smallint been_there_done_that;
-
- if (been_there_done_that)
+ /* Don't recurse */
+ if (__pagesize)
return;
- been_there_done_that++;
/* Setup an initial value. This may not be perfect, but is
* better than malloc using __pagesize=0 for atexit, ctors, etc. */
__pagesize = PAGE_SIZE;
#ifdef __UCLIBC_HAS_THREADS__
+
+#if defined (__UCLIBC_HAS_THREADS_NATIVE__) && !defined (SHARED)
+ /* Unlike in the dynamically linked case the dynamic linker has not
+ taken care of initializing the TLS data structures. */
+ __libc_setup_tls (TLS_TCB_SIZE, TLS_TCB_ALIGN);
+#endif
+
/* Before we start initializing uClibc we have to call
* __pthread_initialize_minimal so we can use pthread_locks
* whenever they are needed.
*/
+#if !defined (__UCLIBC_HAS_THREADS_NATIVE__) || defined (SHARED)
if (likely(__pthread_initialize_minimal!=NULL))
+#endif
__pthread_initialize_minimal();
#endif
@@ -205,21 +271,18 @@ void __uClibc_init(void)
stack_chk_guard = _dl_setup_stack_chk_guard();
# ifdef THREAD_SET_STACK_GUARD
THREAD_SET_STACK_GUARD (stack_chk_guard);
-# ifdef __UCLIBC_HAS_SSP_COMPAT__
- __guard = stack_chk_guard;
-# endif
# else
__stack_chk_guard = stack_chk_guard;
-# if !defined __HAVE_SHARED__ && defined __UCLIBC_HAS_SSP_COMPAT__
- __guard = stack_chk_guard;
-# endif
+# endif
+# ifdef __UCLIBC_HAS_SSP_COMPAT__
+ __guard = stack_chk_guard;
# endif
# endif
#endif
#ifdef __UCLIBC_HAS_LOCALE__
/* Initialize the global locale structure. */
- if (likely(_locale_init!=NULL))
+ if (likely(not_null_ptr(_locale_init)))
_locale_init();
#endif
@@ -229,11 +292,10 @@ void __uClibc_init(void)
* Thus we get a nice size savings because the stdio functions
* won't be pulled into the final static binary unless used.
*/
- if (likely(_stdio_init != NULL))
+ if (likely(not_null_ptr(_stdio_init)))
_stdio_init();
}
-libc_hidden_def(__uClibc_init)
#ifdef __UCLIBC_CTOR_DTOR__
void attribute_hidden (*__app_fini)(void) = NULL;
@@ -241,8 +303,7 @@ void attribute_hidden (*__app_fini)(void) = NULL;
void attribute_hidden (*__rtld_fini)(void) = NULL;
-extern void __uClibc_fini(void);
-libc_hidden_proto(__uClibc_fini)
+extern void __uClibc_fini(void) attribute_hidden;
void __uClibc_fini(void)
{
#ifdef __UCLIBC_CTOR_DTOR__
@@ -261,7 +322,11 @@ void __uClibc_fini(void)
if (__rtld_fini != NULL)
(__rtld_fini)();
}
-libc_hidden_def(__uClibc_fini)
+
+#ifndef SHARED
+extern void __nptl_deallocate_tsd (void) __attribute ((weak));
+extern unsigned int __nptl_nthreads __attribute ((weak));
+#endif
/* __uClibc_main is the new main stub for uClibc. This function is
* called from crt1 (version 0.9.28 or newer), after ALL shared libraries
@@ -269,16 +334,22 @@ libc_hidden_def(__uClibc_fini)
*/
void __uClibc_main(int (*main)(int, char **, char **), int argc,
char **argv, void (*app_init)(void), void (*app_fini)(void),
- void (*rtld_fini)(void), void *stack_end) attribute_noreturn;
+ void (*rtld_fini)(void),
+ void *stack_end attribute_unused) attribute_noreturn;
void __uClibc_main(int (*main)(int, char **, char **), int argc,
char **argv, void (*app_init)(void), void (*app_fini)(void),
- void (*rtld_fini)(void), void *stack_end)
+ void (*rtld_fini)(void), void *stack_end attribute_unused)
{
-#ifndef __ARCH_HAS_NO_LDSO__
+#if !defined __ARCH_HAS_NO_LDSO__ && !defined SHARED
unsigned long *aux_dat;
ElfW(auxv_t) auxvt[AT_EGID + 1];
#endif
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ /* Result of the 'main' function. */
+ int result;
+#endif
+
#ifndef SHARED
__libc_stack_end = stack_end;
#endif
@@ -289,13 +360,13 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
__environ = &argv[argc + 1];
/* If the first thing after argv is the arguments
- * the the environment is empty. */
+ * then the environment is empty. */
if ((char *) __environ == *argv) {
/* Make __environ point to the NULL at argv[argc] */
__environ = &argv[argc];
}
-#ifndef __ARCH_HAS_NO_LDSO__
+#if !defined __ARCH_HAS_NO_LDSO__ && !defined SHARED
/* Pull stuff from the ELF header when possible */
memset(auxvt, 0x00, sizeof(auxvt));
aux_dat = (unsigned long*)__environ;
@@ -310,6 +381,10 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
}
aux_dat += 2;
}
+ /* Get the program headers (_dl_phdr) from the aux vector
+ It will be used into __libc_setup_tls. */
+
+ _dl_aux_init (auxvt);
#endif
/* We need to initialize uClibc. If we are dynamically linked this
@@ -318,31 +393,39 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
__uClibc_init();
#ifndef __ARCH_HAS_NO_LDSO__
- /* Make certain getpagesize() gives the correct answer */
- __pagesize = (auxvt[AT_PAGESZ].a_un.a_val)? auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
+ /* Make certain getpagesize() gives the correct answer.
+ * _dl_pagesize is defined into ld.so if SHARED or into libc.a otherwise. */
+ __pagesize = _dl_pagesize;
+#ifndef SHARED
/* Prevent starting SUID binaries where the stdin. stdout, and
* stderr file descriptors are not already opened. */
if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
(auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
(auxvt[AT_UID].a_un.a_val != auxvt[AT_EUID].a_un.a_val ||
auxvt[AT_GID].a_un.a_val != auxvt[AT_EGID].a_un.a_val)))
+#else
+ if (_dl_secure)
+#endif
{
__check_one_fd (STDIN_FILENO, O_RDONLY | O_NOFOLLOW);
__check_one_fd (STDOUT_FILENO, O_RDWR | O_NOFOLLOW);
__check_one_fd (STDERR_FILENO, O_RDWR | O_NOFOLLOW);
+ _pe_secure = 1 ;
}
+ else
+ _pe_secure = 0 ;
#endif
__uclibc_progname = *argv;
-#ifdef __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__
+#if defined __UCLIBC_HAS___PROGNAME__ || (defined __USE_GNU && defined __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__)
if (*argv != NULL) {
- program_invocation_name = *argv;
- program_invocation_short_name = strrchr(*argv, '/');
- if (program_invocation_short_name != NULL)
- ++program_invocation_short_name;
+ __progname_full = *argv;
+ __progname = strrchr(*argv, '/');
+ if (__progname != NULL)
+ ++__progname;
else
- program_invocation_short_name = program_invocation_name;
+ __progname = *argv;
}
#endif
@@ -385,41 +468,62 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
* have resulted in errno being set nonzero, so set it to 0 before
* we call main.
*/
- if (likely(__errno_location!=NULL))
+ if (likely(not_null_ptr(__errno_location)))
*(__errno_location()) = 0;
/* Set h_errno to 0 as well */
- if (likely(__h_errno_location!=NULL))
+ if (likely(not_null_ptr(__h_errno_location)))
*(__h_errno_location()) = 0;
- /*
- * Finally, invoke application's main and then exit.
- */
- exit(main(argc, argv, __environ));
-}
+#if defined HAVE_CLEANUP_JMP_BUF && defined __UCLIBC_HAS_THREADS_NATIVE__
+ /* Memory for the cancellation buffer. */
+ struct pthread_unwind_buf unwind_buf;
-#if defined(__UCLIBC_HAS_THREADS__) && !defined(SHARED)
-/* Weaks for internal library use only.
- *
- * We need to define weaks here to cover all the pthread functions that
- * libc itself will use so that we aren't forced to link libc against
- * libpthread. This file is only used in libc.a and since we have
- * weaks here, they will be automatically overridden by libpthread.a
- * if it gets linked in.
- */
+ int not_first_call;
+ not_first_call =
+ setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
+ if (__builtin_expect (! not_first_call, 1))
+ {
+ struct pthread *self = THREAD_SELF;
-static int __pthread_return_0 (void) { return 0; }
-static void __pthread_return_void (void) { return; }
+ /* Store old info. */
+ unwind_buf.priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
+ unwind_buf.priv.data.cleanup = THREAD_GETMEM (self, cleanup);
-weak_alias (__pthread_return_0, __pthread_mutex_init)
-weak_alias (__pthread_return_0, __pthread_mutex_lock)
-weak_alias (__pthread_return_0, __pthread_mutex_trylock)
-weak_alias (__pthread_return_0, __pthread_mutex_unlock)
-weak_alias (__pthread_return_void, _pthread_cleanup_push_defer)
-weak_alias (__pthread_return_void, _pthread_cleanup_pop_restore)
-# ifdef __UCLIBC_HAS_THREADS_NATIVE__
-weak_alias (__pthread_return_0, __pthread_mutexattr_init)
-weak_alias (__pthread_return_0, __pthread_mutexattr_destroy)
-weak_alias (__pthread_return_0, __pthread_mutexattr_settype)
+ /* Store the new cleanup handler info. */
+ THREAD_SETMEM (self, cleanup_jmp_buf, &unwind_buf);
+
+ /* Run the program. */
+ result = main (argc, argv, __environ);
+ }
+ else
+ {
+ /* Remove the thread-local data. */
+# ifdef SHARED
+ __libc_pthread_functions.ptr__nptl_deallocate_tsd ();
+# else
+ __nptl_deallocate_tsd ();
+# endif
+
+ /* One less thread. Decrement the counter. If it is zero we
+ terminate the entire process. */
+ result = 0;
+# ifdef SHARED
+ unsigned int *const ptr = __libc_pthread_functions.ptr_nthreads;
+# else
+ unsigned int *const ptr = &__nptl_nthreads;
# endif
+
+ if (! atomic_decrement_and_test (ptr))
+ /* Not much left to do but to exit the thread, not the process. */
+ __exit_thread_inline (0);
+ }
+
+ exit (result);
+#else
+ /*
+ * Finally, invoke application's main and then exit.
+ */
+ exit (main (argc, argv, __environ));
#endif
+}
diff --git a/libc/misc/internals/errno.c b/libc/misc/internals/errno.c
index fcf143fb5..d9908853d 100644
--- a/libc/misc/internals/errno.c
+++ b/libc/misc/internals/errno.c
@@ -1,15 +1,14 @@
-#include "internal_errno.h"
+#include <features.h>
+#include <errno.h>
+#undef errno
-#ifdef __UCLIBC_HAS_THREADS__
-libc_hidden_proto(errno)
-libc_hidden_proto(h_errno)
-#endif
+#ifdef __UCLIBC_HAS_TLS__
+__thread int errno;
+extern __thread int __libc_errno __attribute__ ((alias ("errno"))) attribute_hidden;
+#else
+extern int errno;
int errno = 0;
-int h_errno = 0;
-
-#ifdef __UCLIBC_HAS_THREADS__
-libc_hidden_def(errno)
-weak_alias(errno, _errno)
-libc_hidden_def(h_errno)
-weak_alias(h_errno, _h_errno)
+# ifdef __UCLIBC_HAS_THREADS__
+strong_alias(errno,_errno)
+# endif
#endif
diff --git a/libc/misc/internals/h_errno.c b/libc/misc/internals/h_errno.c
new file mode 100644
index 000000000..8e457501e
--- /dev/null
+++ b/libc/misc/internals/h_errno.c
@@ -0,0 +1,14 @@
+#include <features.h>
+#include <netdb.h>
+#undef h_errno
+
+#ifdef __UCLIBC_HAS_TLS__
+__thread int h_errno;
+extern __thread int __libc_h_errno __attribute__ ((alias ("h_errno"))) attribute_hidden;
+#else
+extern int h_errno;
+int h_errno = 0;
+# ifdef __UCLIBC_HAS_THREADS__
+strong_alias(h_errno,_h_errno)
+# endif
+#endif
diff --git a/libc/misc/internals/internal_errno.h b/libc/misc/internals/internal_errno.h
deleted file mode 100644
index a93d0bf02..000000000
--- a/libc/misc/internals/internal_errno.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- *
- */
-
-#include <features.h>
-#include <errno.h>
-#include <netdb.h>
-
-#undef errno
-#undef h_errno
-
-extern int h_errno;
-extern int errno;
-
-#ifdef __UCLIBC_HAS_THREADS__
-libc_hidden_proto(h_errno)
-libc_hidden_proto(errno)
-#endif
diff --git a/libc/misc/internals/parse_config.c b/libc/misc/internals/parse_config.c
new file mode 100644
index 000000000..b79b7a081
--- /dev/null
+++ b/libc/misc/internals/parse_config.c
@@ -0,0 +1,278 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * config file parser helper
+ *
+ * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ * Also for use in uClibc (http://uclibc.org/) licensed under LGPLv2.1 or later.
+ */
+
+#if !defined _LIBC
+#include "libbb.h"
+
+#if defined ENABLE_PARSE && ENABLE_PARSE
+int parse_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int parse_main(int argc UNUSED_PARAM, char **argv)
+{
+ const char *delims = "# \t";
+ unsigned flags = PARSE_NORMAL;
+ int mintokens = 0, ntokens = 128;
+
+ opt_complementary = "-1:n+:m+:f+";
+ getopt32(argv, "n:m:d:f:", &ntokens, &mintokens, &delims, &flags);
+ //argc -= optind;
+ argv += optind;
+ while (*argv) {
+ parser_t *p = config_open(*argv);
+ if (p) {
+ int n;
+ char **t = xmalloc(sizeof(char *) * ntokens);
+ while ((n = config_read(p, t, ntokens, mintokens, delims, flags)) != 0) {
+ for (int i = 0; i < n; ++i)
+ printf("[%s]", t[i]);
+ puts("");
+ }
+ config_close(p);
+ }
+ argv++;
+ }
+ return EXIT_SUCCESS;
+}
+#endif
+#else
+# include <unistd.h>
+# include <string.h>
+# include <malloc.h>
+# include <bits/uClibc_page.h>
+# include "internal/parse_config.h"
+# ifndef FAST_FUNC
+# define FAST_FUNC
+# endif
+# define fopen_or_warn_stdin fopen
+# define bb_error_msg(...)
+# define xstrdup strdup
+# define xfunc_die() return 0
+/* Read up to EOF or EOL, treat line-continuations as extending the line.
+ Return number of bytes read into .line, -1 otherwise */
+static off_t bb_get_chunk_with_continuation(parser_t* parsr)
+{
+ off_t pos = 0;
+ char *chp;
+
+ while (1) {
+ if (fgets(parsr->line + pos, parsr->line_len - pos, parsr->fp) == NULL) {
+ memset(parsr->line, 0, parsr->line_len);
+ pos = -1;
+ break;
+ }
+ pos += strlen(parsr->line + pos);
+ chp = strchr(parsr->line, '\n');
+ if (chp) {
+ --pos;
+ if (--*chp == '\\')
+ --pos;
+ else
+ break;
+ } else if (parsr->allocated) {
+ parsr->line_len += PAGE_SIZE;
+ parsr->data = realloc(parsr->data,
+ parsr->data_len + parsr->line_len);
+ parsr->line = parsr->data + parsr->data_len;
+ } else {
+ /* discard rest of line if not enough space in buffer */
+ int c;
+ do {
+ c = fgetc(parsr->fp);
+ } while (c != EOF && c != '\n');
+ break;
+ }
+ }
+ return pos;
+}
+#endif
+
+/*
+
+Typical usage:
+
+----- CUT -----
+ char *t[3]; // tokens placeholder
+ parser_t *p = config_open(filename);
+ if (p) {
+ // parse line-by-line
+ while (config_read(p, t, 3, 0, delimiters, flags)) { // 1..3 tokens
+ // use tokens
+ bb_error_msg("TOKENS: [%s][%s][%s]", t[0], t[1], t[2]);
+ }
+ ...
+ // free parser
+ config_close(p);
+ }
+----- CUT -----
+
+*/
+
+static __always_inline parser_t * FAST_FUNC config_open2(const char *filename,
+ FILE* FAST_FUNC (*fopen_func)(const char *path, const char *mode))
+{
+ parser_t *parser;
+ FILE* fp;
+
+ fp = fopen_func(filename, "r");
+ if (!fp)
+ return NULL;
+ parser = calloc(1, sizeof(*parser));
+ if (parser) {
+ parser->fp = fp;
+ }
+ return parser;
+}
+
+parser_t * FAST_FUNC config_open(const char *filename)
+{
+ return config_open2(filename, fopen_or_warn_stdin);
+}
+
+#ifdef UNUSED
+static void config_free_data(parser_t *parser)
+{
+ free(parser->data);
+ parser->data = parser->line = NULL;
+}
+#endif
+
+void FAST_FUNC config_close(parser_t *parser)
+{
+ if (parser) {
+ fclose(parser->fp);
+ if (parser->allocated)
+ free(parser->data);
+ free(parser);
+ }
+}
+
+/*
+0. If parser is NULL return 0.
+1. Read a line from config file. If nothing to read then return 0.
+ Handle continuation character. Advance lineno for each physical line.
+ Discard everything past comment character.
+2. if PARSE_TRIM is set (default), remove leading and trailing delimiters.
+3. If resulting line is empty goto 1.
+4. Look for first delimiter. If !PARSE_COLLAPSE or !PARSE_TRIM is set then
+ remember the token as empty.
+5. Else (default) if number of seen tokens is equal to max number of tokens
+ (token is the last one) and PARSE_GREEDY is set then the remainder
+ of the line is the last token.
+ Else (token is not last or PARSE_GREEDY is not set) just replace
+ first delimiter with '\0' thus delimiting the token.
+6. Advance line pointer past the end of token. If number of seen tokens
+ is less than required number of tokens then goto 4.
+7. Check the number of seen tokens is not less the min number of tokens.
+ Complain or die otherwise depending on PARSE_MIN_DIE.
+8. Return the number of seen tokens.
+
+mintokens > 0 make config_read() print error message if less than mintokens
+(but more than 0) are found. Empty lines are always skipped (not warned about).
+*/
+#undef config_read
+int FAST_FUNC config_read(parser_t *parser, char ***tokens,
+ unsigned flags, const char *delims)
+{
+ char *line;
+ int ntokens, mintokens;
+ off_t len;
+ int t;
+
+ if (parser == NULL)
+ return 0;
+ ntokens = flags & 0xFF;
+ mintokens = (flags & 0xFF00) >> 8;
+again:
+ if (parser->data == NULL) {
+ if (parser->line_len == 0)
+ parser->line_len = 81;
+ if (parser->data_len == 0)
+ parser->data_len += 1 + ntokens * sizeof(char *);
+ parser->data = malloc(parser->data_len + parser->line_len);
+ if (parser->data == NULL)
+ return 0;
+ parser->allocated |= 1;
+ } /* else { assert(parser->data_len > 0); } */
+ parser->line = parser->data + parser->data_len;
+ /*config_free_data(parser);*/
+
+ /* Read one line (handling continuations with backslash) */
+ len = bb_get_chunk_with_continuation(parser);
+ if (len == -1)
+ return 0;
+ line = parser->line;
+
+ /* Skip multiple token-delimiters in the start of line? */
+ if (flags & PARSE_TRIM)
+ line += strspn(line, delims + 1);
+
+ if (line[0] == '\0' || line[0] == delims[0])
+ goto again;
+
+ *tokens = (char **) parser->data;
+ memset(*tokens, 0, sizeof(*tokens[0]) * ntokens);
+
+ /* Tokenize the line */
+ for (t = 0; *line && *line != delims[0] && t < ntokens; t++) {
+ /* Pin token */
+ *(*tokens + t) = line;
+
+ /* Combine remaining arguments? */
+ if ((t != ntokens-1) || !(flags & PARSE_GREEDY)) {
+ /* Vanilla token, find next delimiter */
+ line += strcspn(line, delims[0] ? delims : delims + 1);
+ } else {
+ /* Combining, find comment char if any */
+ line = strchrnul(line, delims[0]);
+
+ /* Trim any extra delimiters from the end */
+ if (flags & PARSE_TRIM) {
+ while (strchr(delims + 1, line[-1]) != NULL)
+ line--;
+ }
+ }
+
+ /* Token not terminated? */
+ if (line[0] == delims[0])
+ *line = '\0';
+ else if (line[0] != '\0')
+ *(line++) = '\0';
+
+#if 0 /* unused so far */
+ if (flags & PARSE_ESCAPE) {
+ const char *from;
+ char *to;
+
+ from = to = tokens[t];
+ while (*from) {
+ if (*from == '\\') {
+ from++;
+ *to++ = bb_process_escape_sequence(&from);
+ } else {
+ *to++ = *from++;
+ }
+ }
+ *to = '\0';
+ }
+#endif
+
+ /* Skip possible delimiters */
+ if (flags & PARSE_COLLAPSE)
+ line += strspn(line, delims + 1);
+ }
+
+ if (t < mintokens) {
+ bb_error_msg(/*"bad line %u: "*/"%d tokens found, %d needed",
+ /*parser->lineno, */t, mintokens);
+ if (flags & PARSE_MIN_DIE)
+ xfunc_die();
+ goto again;
+ }
+ return t;
+}
diff --git a/libc/misc/internals/tempname.c b/libc/misc/internals/tempname.c
index 0883259bd..7654eb433 100644
--- a/libc/misc/internals/tempname.c
+++ b/libc/misc/internals/tempname.c
@@ -13,8 +13,7 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ see <http://www.gnu.org/licenses/>. */
/* March 11, 2002 Manuel Novoa III
*
@@ -45,20 +44,6 @@
#include <sys/time.h>
#include "tempname.h"
-/* Experimentally off - libc_hidden_proto(strlen) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-libc_hidden_proto(sprintf)
-libc_hidden_proto(mkdir)
-libc_hidden_proto(open)
-#ifdef __UCLIBC_HAS_LFS__
-libc_hidden_proto(open64)
-#endif
-libc_hidden_proto(read)
-libc_hidden_proto(close)
-libc_hidden_proto(getpid)
-libc_hidden_proto(stat)
-libc_hidden_proto(gettimeofday)
-
/* Return nonzero if DIR is an existent directory. */
static int direxists (const char *dir)
{
@@ -72,11 +57,14 @@ static int direxists (const char *dir)
for use with mk[s]temp. Will fail (-1) if DIR is non-null and
doesn't exist, none of the searched dirs exists, or there's not
enough space in TMPL. */
-int attribute_hidden ___path_search (char *tmpl, size_t tmpl_len, const char *dir,
+int ___path_search (char *tmpl, size_t tmpl_len, const char *dir,
const char *pfx /*, int try_tmpdir*/)
{
- //const char *d;
- size_t dlen, plen;
+ /*const char *d; */
+ /* dir and pfx lengths should always fit into an int,
+ so don't bother using size_t here. Especially since
+ the printf func requires an int for precision (%*s). */
+ int dlen, plen;
if (!pfx || !pfx[0])
{
@@ -121,7 +109,7 @@ int attribute_hidden ___path_search (char *tmpl, size_t tmpl_len, const char *di
dlen--; /* remove trailing slashes */
/* check we have room for "${dir}/${pfx}XXXXXX\0" */
- if (tmpl_len < dlen + 1 + plen + 6 + 1)
+ if (tmpl_len < (size_t)dlen + 1 + plen + 6 + 1)
{
__set_errno (EINVAL);
return -1;
@@ -175,21 +163,22 @@ static void brain_damaged_fillrand(unsigned char *buf, unsigned int len)
}
}
-/* Generate a temporary file name based on TMPL. TMPL must match the
- rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
- does not exist at the time of the call to __gen_tempname. TMPL is
- overwritten with the result.
+/* Generate a temporary file name based on TMPL. TMPL must match the
+ rules for mk[s]temp[s] (i.e. end in "prefixXXXXXXsuffix"). The name
+ constructed does not exist at the time of the call to __gen_tempname.
+ TMPL is overwritten with the result.
KIND may be one of:
__GT_NOCREATE: simply verify that the name does not exist
- at the time of the call.
+ at the time of the call. mode argument is ignored.
__GT_FILE: create the file using open(O_CREAT|O_EXCL)
- and return a read-write fd. The file is mode 0600.
+ and return a read-write fd with given mode.
__GT_BIGFILE: same as __GT_FILE but use open64().
- __GT_DIR: create a directory, which will be mode 0700.
+ __GT_DIR: create a directory with given mode.
*/
-int attribute_hidden __gen_tempname (char *tmpl, int kind)
+int attribute_hidden __gen_tempname (char *tmpl, int kind, int flags,
+ int suffixlen, mode_t mode)
{
char *XXXXXX;
unsigned int i;
@@ -199,15 +188,16 @@ int attribute_hidden __gen_tempname (char *tmpl, int kind)
len = strlen (tmpl);
/* This is where the Xs start. */
- XXXXXX = tmpl + len - 6;
- if (len < 6 || strcmp (XXXXXX, "XXXXXX"))
+ XXXXXX = tmpl + len - 6 - suffixlen;
+ if (len < 6 || suffixlen < 0 || suffixlen > len - 6
+ || strncmp (XXXXXX, "XXXXXX", 6))
{
__set_errno (EINVAL);
return -1;
}
for (i = 0; i < TMP_MAX; ++i) {
- int j;
+ unsigned char j;
/* Get some random data. */
if (fillrand(randomness, sizeof(randomness)) != sizeof(randomness)) {
/* if random device nodes failed us, lets use the braindamaged ver */
@@ -231,15 +221,15 @@ int attribute_hidden __gen_tempname (char *tmpl, int kind)
fd = 0;
}
case __GT_FILE:
- fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | flags, mode);
break;
#if defined __UCLIBC_HAS_LFS__
case __GT_BIGFILE:
- fd = open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ fd = open64 (tmpl, O_RDWR | O_CREAT | O_EXCL | flags, mode);
break;
#endif
case __GT_DIR:
- fd = mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
+ fd = mkdir (tmpl, mode);
break;
default:
fd = -1;
diff --git a/libc/misc/internals/tempname.h b/libc/misc/internals/tempname.h
index ac40bef6e..cc20f756c 100644
--- a/libc/misc/internals/tempname.h
+++ b/libc/misc/internals/tempname.h
@@ -3,13 +3,15 @@
#define __need_size_t
#include <stddef.h>
+#include <sys/types.h>
/* Disable support for $TMPDIR */
extern int ___path_search (char *tmpl, size_t tmpl_len, const char *dir,
const char *pfx /*, int try_tmpdir */) attribute_hidden;
#define __path_search(tmpl, tmpl_len, dir, pfx, try_tmpdir) ___path_search(tmpl, tmpl_len, dir, pfx)
-extern int __gen_tempname (char *__tmpl, int __kind) attribute_hidden;
+extern int __gen_tempname (char *__tmpl, int __kind, int flags,
+ int suffixlen, mode_t mode) attribute_hidden;
/* The __kind argument to __gen_tempname may be one of: */
#define __GT_FILE 0 /* create a file */
diff --git a/libc/misc/locale/Makefile.in b/libc/misc/locale/Makefile.in
index 1991d04e3..3db6d5c5c 100644
--- a/libc/misc/locale/Makefile.in
+++ b/libc/misc/locale/Makefile.in
@@ -1,28 +1,27 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
+subdirs += libc/misc/locale
+
# multi source locale.c
-CSRC := setlocale.c localeconv.c _locale_init.c nl_langinfo.c
-ifeq ($(UCLIBC_HAS_LOCALE),y)
-CSRC += newlocale.c __locale_mbrtowc_l.c
-endif
-ifeq ($(UCLIBC_HAS_XLOCALE),y)
-CSRC += nl_langinfo_l.c duplocale.c freelocale.c uselocale.c __curlocale.c
-endif
+CSRC-y := setlocale.c localeconv.c _locale_init.c nl_langinfo.c
+CSRC-$(UCLIBC_HAS_LOCALE) += newlocale.c __locale_mbrtowc_l.c
+CSRC-$(UCLIBC_HAS_XLOCALE) += nl_langinfo_l.c duplocale.c freelocale.c \
+ uselocale.c __curlocale.c
MISC_LOCALE_DIR := $(top_srcdir)libc/misc/locale
MISC_LOCALE_OUT := $(top_builddir)libc/misc/locale
-MISC_LOCALE_SRC := $(patsubst %.c,$(MISC_LOCALE_DIR)/%.c,$(CSRC))
-MISC_LOCALE_OBJ := $(patsubst %.c,$(MISC_LOCALE_OUT)/%.o,$(CSRC))
+MISC_LOCALE_SRC := $(patsubst %.c,$(MISC_LOCALE_DIR)/%.c,$(CSRC-y))
+MISC_LOCALE_OBJ := $(patsubst %.c,$(MISC_LOCALE_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_LOCALE_OBJ)
-objclean-y += misc_locale_objclean
+objclean-y += CLEAN_libc/misc/locale
-misc_locale_objclean:
- $(RM) $(MISC_LOCALE_OUT)/*.{o,os}
+CLEAN_libc/misc/locale:
+ $(do_rm) $(addprefix $(MISC_LOCALE_OUT)/*., o os)
diff --git a/libc/misc/locale/locale.c b/libc/misc/locale/locale.c
index 858a02c33..68e54413e 100644
--- a/libc/misc/locale/locale.c
+++ b/libc/misc/locale/locale.c
@@ -11,8 +11,8 @@
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
*/
/* Nov. 1, 2002
@@ -58,20 +58,6 @@
#include <ctype.h>
#include <stdio.h>
-/* Experimentally off - libc_hidden_proto(memcpy) */
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(strtok_r) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strcpy) */
-/* Experimentally off - libc_hidden_proto(strncmp) */
-/* Experimentally off - libc_hidden_proto(strchr) */
-libc_hidden_proto(getenv)
-#ifdef __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__C_ctype_toupper)
-#endif
-/*libc_hidden_proto(fflush)*/
-
#ifdef __UCLIBC_MJN3_ONLY__
#ifdef L_setlocale
#warning TODO: Make the link_warning()s a config option?
@@ -99,19 +85,17 @@ libc_hidden_proto(__C_ctype_toupper)
#endif
#endif
-/* Need to include this before locale.h and xlocale.h! */
+/* Need to include this before locale.h! */
#include <bits/uClibc_locale.h>
#undef CODESET_LIST
#define CODESET_LIST (__locale_mmap->codeset_list)
#ifdef __UCLIBC_HAS_XLOCALE__
-#include <xlocale.h>
#include <locale.h>
-#else /* __UCLIBC_HAS_XLOCALE__ */
+#else /* __UCLIBC_HAS_XLOCALE__ */
/* We need this internally... */
#define __UCLIBC_HAS_XLOCALE__ 1
-#include <xlocale.h>
#include <locale.h>
#undef __UCLIBC_HAS_XLOCALE__
#endif /* __UCLIBC_HAS_XLOCALE__ */
@@ -120,14 +104,14 @@ libc_hidden_proto(__C_ctype_toupper)
#define LOCALE_NAMES (__locale_mmap->locale_names5)
#define LOCALES (__locale_mmap->locales)
-#define LOCALE_AT_MODIFIERS (__locale_mmap->locale_at_modifiers)
+#define LOCALE_AT_MODIFIERS (__locale_mmap->locale_at_modifiers)
#define CATEGORY_NAMES (__locale_mmap->lc_names)
#ifdef __UCLIBC_MJN3_ONLY__
#warning REMINDER: redo the MAX_LOCALE_STR stuff...
#endif
-#define MAX_LOCALE_STR 256 /* TODO: Only sufficient for current case. */
-#define MAX_LOCALE_CATEGORY_STR 32 /* TODO: Only sufficient for current case. */
+#define MAX_LOCALE_STR 256 /* TODO: Only sufficient for current case. */
+#define MAX_LOCALE_CATEGORY_STR 32 /* TODO: Only sufficient for current case. */
/* Note: Best if MAX_LOCALE_CATEGORY_STR is a power of 2. */
extern int _locale_set_l(const unsigned char *p, __locale_t base) attribute_hidden;
@@ -169,7 +153,7 @@ char *setlocale(int category, register const char *locale)
: NULL;
}
-#else /* ---------------------------------------------- __LOCALE_C_ONLY */
+#else /* ---------------------------------------------- __LOCALE_C_ONLY */
#ifdef __UCLIBC_HAS_THREADS__
link_warning(setlocale,"REMINDER: The 'setlocale' function is _not_ threadsafe except for simple queries.")
@@ -193,8 +177,6 @@ static const char utf8[] = "UTF-8";
*/
static char hr_locale[(MAX_LOCALE_CATEGORY_STR * LC_ALL) + MAX_LOCALE_STR];
-/* Experimentally off - libc_hidden_proto(stpcpy) */
-libc_hidden_proto(newlocale)
static void update_hr_locale(const unsigned char *spec)
{
@@ -230,7 +212,8 @@ static void update_hr_locale(const unsigned char *spec)
+ __LOCALE_DATA_WIDTH_LOCALES * ((((int)(*s & 0x7f)) << 7)
+ (s[1] & 0x7f));
if (category == LC_ALL) {
- n = stpcpy(n, CATEGORY_NAMES + (int) CATEGORY_NAMES[i]);
+ /* CATEGORY_NAMES is unsigned char* */
+ n = stpcpy(n, (char*) CATEGORY_NAMES + (int) CATEGORY_NAMES[i]);
*n++ = '=';
}
if (*loc == 0) {
@@ -248,12 +231,12 @@ static void update_hr_locale(const unsigned char *spec)
if (loc[2] == 2) {
n = stpcpy(n, utf8);
} else if (loc[2] >= 3) {
- n = stpcpy(n, CODESET_LIST + (int)(CODESET_LIST[loc[2] - 3]));
+ n = stpcpy(n, (char*) CODESET_LIST + (int)(CODESET_LIST[loc[2] - 3]));
}
if (at) {
const char *q;
*n++ = '@';
- q = LOCALE_AT_MODIFIERS;
+ q = (char*) LOCALE_AT_MODIFIERS;
do {
if (q[1] == at) {
n = stpcpy(n, q+2);
@@ -267,7 +250,7 @@ static void update_hr_locale(const unsigned char *spec)
}
s += 2;
} while (++i < category);
- *--n = 0; /* Remove trailing ';' and nul-terminate. */
+ *--n = 0; /* Remove trailing ';' and nul-terminate. */
++category;
} while (!done);
@@ -303,7 +286,6 @@ char *setlocale(int category, const char *locale)
* placement of the fields in the struct. If necessary, we could ensure
* this usings an array of offsets but at some size cost. */
-libc_hidden_proto(localeconv)
#ifdef __LOCALE_C_ONLY
@@ -332,14 +314,14 @@ struct lconv *localeconv(void)
return &the_lconv;
}
-#else /* __LOCALE_C_ONLY */
+#else /* __LOCALE_C_ONLY */
static struct lconv the_lconv;
struct lconv *localeconv(void)
{
register char *p = (char *) &the_lconv;
- register char **q = (char **) &(__UCLIBC_CURLOCALE_DATA).decimal_point;
+ register char **q = (char **) &(__UCLIBC_CURLOCALE->decimal_point);
do {
*((char **)p) = *q;
@@ -364,15 +346,7 @@ libc_hidden_def(localeconv)
/**********************************************************************/
#if defined(L__locale_init) && !defined(__LOCALE_C_ONLY)
-libc_hidden_proto(__C_ctype_b)
-libc_hidden_proto(__C_ctype_tolower)
-#ifndef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_b)
-libc_hidden_proto(__ctype_tolower)
-libc_hidden_proto(__ctype_toupper)
-#endif
-
-__uclibc_locale_t __global_locale_data;
+struct __uclibc_locale_struct __global_locale_data;
__locale_t __global_locale = &__global_locale_data;
@@ -609,7 +583,7 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base)
if ((p[2*LC_COLLATE] != s[2*LC_COLLATE])
|| (p[2*LC_COLLATE + 1] != s[2*LC_COLLATE + 1])
) {
- row = (((int)(*p & 0x7f)) << 7) + (p[1] & 0x7f);
+ row = (((int)(*p & 0x7f)) << 7) + (p[1] & 0x7f);
assert(row < __LOCALE_DATA_NUM_LOCALES);
if (!init_cur_collate(__locale_mmap->locales[ __LOCALE_DATA_WIDTH_LOCALES
* row + 3 + LC_COLLATE ],
@@ -623,7 +597,7 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base)
do {
if ((*p != *s) || (p[1] != s[1])) {
- row = (((int)(*p & 0x7f)) << 7) + (p[1] & 0x7f);
+ row = (((int)(*p & 0x7f)) << 7) + (p[1] & 0x7f);
assert(row < __LOCALE_DATA_NUM_LOCALES);
*s = *p;
@@ -644,8 +618,8 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base)
io = (const uint16_t *)( ((char *)__locale_mmap) + *++stp );
ii = (const uint16_t *)( ((char *)__locale_mmap) + *++stp );
d = (const unsigned char *)( ((char *)__locale_mmap) + *++stp );
- for (c=0 ; c < len ; c++) {
- *(x + c) = d + ii[ r[crow + c] + io[c] ];
+ for (c = 0; c < len; c++) {
+ x[c] = (char*)(d + ii[r[crow + c] + io[c]]);
}
}
if (i == LC_CTYPE) {
@@ -658,7 +632,7 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base)
/* TODO - fix for bcc */
base->mb_cur_max = 6;
} else {
- assert(c==1);
+ assert(c == 1);
base->codeset = ascii;
base->encoding = __ctype_encoding_7_bit;
base->mb_cur_max = 1;
@@ -666,7 +640,8 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base)
} else {
const __codeset_8_bit_t *c8b;
r = CODESET_LIST;
- base->codeset = r + r[c -= 3];
+ c -= 3;
+ base->codeset = (char *) (r + r[c]);
base->encoding = __ctype_encoding_8_bit;
#ifdef __UCLIBC_MJN3_ONLY__
#warning REMINDER: update 8 bit mb_cur_max when translit implemented!
@@ -789,7 +764,7 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base)
+ __UCLIBC_CTYPE_TO_TBL_OFFSET;
base->__ctype_toupper = base->__ctype_toupper_data
+ __UCLIBC_CTYPE_TO_TBL_OFFSET;
-#else /* __UCLIBC_HAS_XLOCALE__ */
+#else /* __UCLIBC_HAS_XLOCALE__ */
__ctype_b = base->__ctype_b_data
+ __UCLIBC_CTYPE_B_TBL_OFFSET;
__ctype_tolower = base->__ctype_tolower_data
@@ -879,17 +854,17 @@ void attribute_hidden _locale_init_l(__locale_t base)
LC_ALL);
++base->category_item_count[0]; /* Increment for codeset entry. */
- base->category_offsets[0] = offsetof(__uclibc_locale_t, outdigit0_mb);
- base->category_offsets[1] = offsetof(__uclibc_locale_t, decimal_point);
- base->category_offsets[2] = offsetof(__uclibc_locale_t, int_curr_symbol);
- base->category_offsets[3] = offsetof(__uclibc_locale_t, abday_1);
-/* base->category_offsets[4] = offsetof(__uclibc_locale_t, collate???); */
- base->category_offsets[5] = offsetof(__uclibc_locale_t, yesexpr);
+ base->category_offsets[0] = offsetof(struct __uclibc_locale_struct, outdigit0_mb);
+ base->category_offsets[1] = offsetof(struct __uclibc_locale_struct, decimal_point);
+ base->category_offsets[2] = offsetof(struct __uclibc_locale_struct, int_curr_symbol);
+ base->category_offsets[3] = offsetof(struct __uclibc_locale_struct, abday_1);
+/* base->category_offsets[4] = offsetof(struct __uclibc_locale_struct, collate???); */
+ base->category_offsets[5] = offsetof(struct __uclibc_locale_struct, yesexpr);
#ifdef __CTYPE_HAS_8_BIT_LOCALES
base->tbl8ctype
= (const unsigned char *) &__locale_mmap->tbl8ctype;
- base->tbl8uplow
+ base->tbl8uplow
= (const unsigned char *) &__locale_mmap->tbl8uplow;
#ifdef __UCLIBC_HAS_WCHAR__
base->tbl8c2wc
@@ -905,7 +880,7 @@ void attribute_hidden _locale_init_l(__locale_t base)
base->tblwuplow
= (const unsigned char *) &__locale_mmap->tblwuplow;
base->tblwuplow_diff
- = (const uint16_t *) &__locale_mmap->tblwuplow_diff;
+ = (const int16_t *) &__locale_mmap->tblwuplow_diff;
/* base->tblwcomb */
/* = (const unsigned char *) &__locale_mmap->tblwcomb; */
/* width?? */
@@ -917,7 +892,7 @@ void attribute_hidden _locale_init_l(__locale_t base)
base->__ctype_b = __C_ctype_b;
base->__ctype_tolower = __C_ctype_tolower;
base->__ctype_toupper = __C_ctype_toupper;
-#else /* __UCLIBC_HAS_XLOCALE__ */
+#else /* __UCLIBC_HAS_XLOCALE__ */
__ctype_b = __C_ctype_b;
__ctype_tolower = __C_ctype_tolower;
__ctype_toupper = __C_ctype_toupper;
@@ -928,11 +903,9 @@ void attribute_hidden _locale_init_l(__locale_t base)
#endif
base->code2flag = __code2flag;
-
- _locale_set_l(C_LOCALE_SELECTOR, base);
+ _locale_set_l((unsigned char*) C_LOCALE_SELECTOR, base);
}
-void _locale_init(void) attribute_hidden;
void _locale_init(void)
{
/* TODO: mmap the locale file */
@@ -967,7 +940,7 @@ void _locale_init(void)
static const unsigned char nl_data[C_LC_ALL + 1 + 90 + 320] = {
/* static const char cat_start[LC_ALL + 1] = { */
- '\x00', '\x0b', '\x0e', '\x24', '\x56', '\x56', '\x5a',
+ '\x00', '\x0b', '\x0e', '\x24', '\x56', '\x56', '\x5a',
/* }; */
/* static const char item_offset[90] = { */
'\x00', '\x02', '\x04', '\x06', '\x08', '\x0a', '\x0c', '\x0e',
@@ -1026,7 +999,6 @@ static const unsigned char nl_data[C_LC_ALL + 1 + 90 + 320] = {
']', '\x00', '^', '[', 'n', 'N', ']', '\x00',
};
-libc_hidden_proto(nl_langinfo)
char *nl_langinfo(nl_item item)
{
unsigned int c;
@@ -1042,13 +1014,11 @@ char *nl_langinfo(nl_item item)
}
libc_hidden_def(nl_langinfo)
-#else /* __LOCALE_C_ONLY */
+#else /* __LOCALE_C_ONLY */
#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
-libc_hidden_proto(nl_langinfo)
-libc_hidden_proto(nl_langinfo_l)
char *nl_langinfo(nl_item item)
{
@@ -1056,13 +1026,13 @@ char *nl_langinfo(nl_item item)
}
libc_hidden_def(nl_langinfo)
-#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
libc_hidden_proto(__XL_NPP(nl_langinfo))
static const char empty[] = "";
-char *__XL_NPP(nl_langinfo)(nl_item item __LOCALE_PARAM )
+char *__XL_NPP(nl_langinfo)(nl_item item __LOCALE_PARAM )
{
unsigned int c = _NL_ITEM_CATEGORY(item);
unsigned int i = _NL_ITEM_INDEX(item);
@@ -1084,8 +1054,7 @@ libc_hidden_def(__XL_NPP(nl_langinfo))
/**********************************************************************/
#ifdef L_newlocale
-/* Experimentally off - libc_hidden_proto(stpcpy) */
-libc_hidden_proto(newlocale)
+#warning mask defines for extra locale categories
#ifdef __UCLIBC_MJN3_ONLY__
#warning TODO: Move posix and utf8 strings.
@@ -1117,7 +1086,7 @@ static int find_locale(int category_mask, const char *p,
/* locale name at least 5 chars long and 3rd char is '_' */
s = LOCALE_AT_MODIFIERS;
do {
- if (!strcmp(s+2, q+1)) {
+ if (!strcmp((char*) (s + 2), q + 1)) {
break;
}
s += 2 + *s; /* TODO - fix this throughout */
@@ -1142,11 +1111,11 @@ static int find_locale(int category_mask, const char *p,
/* TODO: maybe CODESET_LIST + *s ??? */
/* 7bit is 1, UTF-8 is 2, 8-bit is >= 3 */
codeset = 2;
- if (strcasecmp(utf8,p+6) != 0) {/* TODO - fix! */
+ if (strcasecmp(utf8, p + 6) != 0) {/* TODO - fix! */
s = CODESET_LIST;
do {
++codeset; /* Increment codeset first. */
- if (!strcmp(CODESET_LIST+*s, p+6)) {
+ if (!strcmp((char*) CODESET_LIST + *s, p + 6)) {
goto FIND_LANG_CULT;
}
} while (*++s);
@@ -1159,7 +1128,7 @@ static int find_locale(int category_mask, const char *p,
do { /* TODO -- do a binary search? */
/* TODO -- fix gen_mmap!*/
++lang_cult; /* Increment first since C/POSIX is 0. */
- if (!strncmp(s,p,5)) { /* Found a matching locale name; */
+ if (!strncmp((char*) s, p, 5)) { /* Found a matching locale name; */
goto FIND_LOCALE;
}
s += 5;
@@ -1217,7 +1186,8 @@ static unsigned char *composite_locale(int category_mask, const char *locale,
t = strtok_r(buf, "=", &e); /* This can't fail because of strchr test above. */
do {
c = 0;
- while (strcmp(CATEGORY_NAMES + (int) CATEGORY_NAMES[c], t)) {
+ /* CATEGORY_NAMES is unsigned char* */
+ while (strcmp((char*) CATEGORY_NAMES + (int) CATEGORY_NAMES[c], t)) {
if (++c == LC_ALL) { /* Unknown category name! */
return NULL;
}
@@ -1242,7 +1212,7 @@ static unsigned char *composite_locale(int category_mask, const char *locale,
__locale_t newlocale(int category_mask, const char *locale, __locale_t base)
{
- const unsigned char *p;
+ const char *p;
int i, j, k;
unsigned char new_selector[LOCALE_SELECTOR_SIZE];
@@ -1250,10 +1220,10 @@ __locale_t newlocale(int category_mask, const char *locale, __locale_t base)
category_mask = LC_ALL_MASK;
}
- if (!locale || (((unsigned int)(category_mask)) > LC_ALL_MASK)) {
- INVALID:
+ if (!locale || ((unsigned)(category_mask) > LC_ALL_MASK)) {
+ INVALID:
__set_errno(EINVAL);
- return NULL; /* No locale or illegal/unsupported category. */
+ return NULL; /* No locale or illegal/unsupported category. */
}
#ifdef __UCLIBC_MJN3_ONLY__
@@ -1262,11 +1232,13 @@ __locale_t newlocale(int category_mask, const char *locale, __locale_t base)
strcpy((char *) new_selector,
(base ? (char *) base->cur_locale : C_LOCALE_SELECTOR));
- if (!*locale) { /* locale == "", so check environment. */
-#ifndef __UCLIBC_HAS_THREADS__
- static /* If no threads, then envstr can be static. */
-#endif /* __UCLIBC_HAS_THREADS__ */
- const char *envstr[4] = { "LC_ALL", NULL, "LANG", posix };
+ if (!locale[0]) { /* locale == "", so check environment. */
+ const char *envstr[4];
+
+ envstr[0] = "LC_ALL";
+ envstr[1] = NULL;
+ envstr[2] = "LANG";
+ envstr[3] = posix;
i = 1;
k = 0;
@@ -1275,12 +1247,16 @@ __locale_t newlocale(int category_mask, const char *locale, __locale_t base)
/* Note: SUSv3 doesn't define a fallback mechanism here.
* So, if LC_ALL is invalid, we do _not_ continue trying
* the other environment vars. */
- envstr[1] = CATEGORY_NAMES + CATEGORY_NAMES[k];
+ envstr[1] = (char*) CATEGORY_NAMES + CATEGORY_NAMES[k];
j = 0;
- do {
+ while (1) {
p = envstr[j];
- } while ((++j < 4) && (!(p = getenv(p)) || !*p));
-
+ if (++j >= 4)
+ break; /* now p == "POSIX" */
+ p = getenv(p);
+ if (p && p[0])
+ break;
+ };
/* The user set something... is it valid? */
/* Note: Since we don't support user-supplied locales and
@@ -1313,9 +1289,9 @@ __locale_t newlocale(int category_mask, const char *locale, __locale_t base)
}
#else
if (!base) {
- if ((base = malloc(sizeof(__uclibc_locale_t))) == NULL) {
+ base = calloc(1, sizeof(struct __uclibc_locale_struct));
+ if (base == NULL)
return base;
- }
_locale_init_l(base);
}
@@ -1324,13 +1300,14 @@ __locale_t newlocale(int category_mask, const char *locale, __locale_t base)
return base;
}
+#ifdef __UCLIBC_HAS_XLOCALE__
libc_hidden_def(newlocale)
+#endif
#endif
/**********************************************************************/
#ifdef L_duplocale
-libc_hidden_proto(duplocale)
#ifdef __UCLIBC_MJN3_ONLY__
#warning REMINDER: When we allocate ctype tables, remember to dup them.
@@ -1344,12 +1321,12 @@ __locale_t duplocale(__locale_t dataset)
assert(dataset != LC_GLOBAL_LOCALE);
- if ((r = malloc(sizeof(__uclibc_locale_t))) != NULL) {
- n = 2*dataset->collate.max_col_index+2;
- if ((i2w = calloc(n, sizeof(uint16_t)))
- != NULL
- ) {
- memcpy(r, dataset, sizeof(__uclibc_locale_t));
+ r = malloc(sizeof(struct __uclibc_locale_struct));
+ if (r != NULL) {
+ n = 2 * dataset->collate.max_col_index + 2;
+ i2w = calloc(n, sizeof(uint16_t));
+ if (i2w != NULL) {
+ memcpy(r, dataset, sizeof(struct __uclibc_locale_struct));
r->collate.index2weight = i2w;
memcpy(i2w, dataset->collate.index2weight, n * sizeof(uint16_t));
} else {
@@ -1359,7 +1336,6 @@ __locale_t duplocale(__locale_t dataset)
}
return r;
}
-libc_hidden_def(duplocale)
#endif
/**********************************************************************/
@@ -1382,7 +1358,6 @@ void freelocale(__locale_t dataset)
/**********************************************************************/
#ifdef L_uselocale
-libc_hidden_proto(uselocale)
__locale_t uselocale(__locale_t dataset)
{
__locale_t old;
@@ -1416,8 +1391,9 @@ libc_hidden_def(uselocale)
__locale_t weak_const_function __curlocale(void)
{
- return __curlocale_var; /* This is overriden by the thread version. */
+ return __curlocale_var; /* This is overriden by the thread version. */
}
+libc_hidden_weak(__curlocale)
__locale_t weak_function __curlocale_set(__locale_t newloc)
{
@@ -1426,6 +1402,7 @@ __locale_t weak_function __curlocale_set(__locale_t newloc)
__curlocale_var = newloc;
return oldloc;
}
+libc_hidden_weak(__curlocale_set)
#endif
diff --git a/libc/misc/mntent/Makefile.in b/libc/misc/mntent/Makefile.in
index 958b119b3..3ced9bbd1 100644
--- a/libc/misc/mntent/Makefile.in
+++ b/libc/misc/mntent/Makefile.in
@@ -1,21 +1,23 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := mntent.c
+subdirs += libc/misc/mntent
+
+CSRC-y := mntent.c
MISC_MNTENT_DIR := $(top_srcdir)libc/misc/mntent
MISC_MNTENT_OUT := $(top_builddir)libc/misc/mntent
-MISC_MNTENT_SRC := $(MISC_MNTENT_DIR)/mntent.c
-MISC_MNTENT_OBJ := $(MISC_MNTENT_OUT)/mntent.o
+MISC_MNTENT_SRC := $(patsubst %.c,$(MISC_MNTENT_DIR)/%.c,$(CSRC-y))
+MISC_MNTENT_OBJ := $(patsubst %.c,$(MISC_MNTENT_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_MNTENT_OBJ)
-objclean-y += misc_mntent_objclean
+objclean-y += CLEAN_libc/misc/mntent
-misc_mntent_objclean:
- $(RM) $(MISC_MNTENT_OUT)/*.{o,os}
+CLEAN_libc/misc/mntent:
+ $(do_rm) $(addprefix $(MISC_MNTENT_OUT)/*., o os)
diff --git a/libc/misc/mntent/mntent.c b/libc/misc/mntent/mntent.c
index f4220784a..608f84c1a 100644
--- a/libc/misc/mntent/mntent.c
+++ b/libc/misc/mntent/mntent.c
@@ -12,26 +12,15 @@
__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
-libc_hidden_proto(getmntent_r)
-libc_hidden_proto(setmntent)
-libc_hidden_proto(endmntent)
-
-/* Experimentally off - libc_hidden_proto(strstr) */
-/* Experimentally off - libc_hidden_proto(strtok_r) */
-libc_hidden_proto(atoi)
-libc_hidden_proto(fopen)
-libc_hidden_proto(fclose)
-libc_hidden_proto(fseek)
-libc_hidden_proto(fgets)
-libc_hidden_proto(abort)
-libc_hidden_proto(fprintf)
+
/* Reentrant version of getmntent. */
struct mntent *getmntent_r (FILE *filep,
struct mntent *mnt, char *buff, int bufsize)
{
+ static const char sep[] = " \t\n";
+
char *cp, *ptrptr;
- const char *sep = " \t\n";
if (!filep || !mnt || !buff)
return NULL;
diff --git a/libc/misc/pthread/Makefile.in b/libc/misc/pthread/Makefile.in
index 0d7a9e49d..2f436ac1c 100644
--- a/libc/misc/pthread/Makefile.in
+++ b/libc/misc/pthread/Makefile.in
@@ -1,17 +1,18 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
+subdirs += libc/misc/pthread
+
MISC_PTHREAD_DIR := $(top_srcdir)libc/misc/pthread
MISC_PTHREAD_OUT := $(top_builddir)libc/misc/pthread
-libc-$(UCLIBC_HAS_THREADS) += $(MISC_PTHREAD_OUT)/unlock.o
-libc-$(UCLIBC_HAS_THREADS) += $(MISC_PTHREAD_OUT)/weaks.o
+libc-shared-$(UCLIBC_HAS_TLS) += $(MISC_PTHREAD_OUT)/tsd.os
-objclean-y += misc_pthread_objclean
+objclean-y += CLEAN_libc/misc/pthread
-misc_pthread_objclean:
- $(RM) $(MISC_PTHREAD_OUT)/*.{o,os,oS}
+CLEAN_libc/misc/pthread:
+ $(do_rm) $(addprefix $(MISC_PTHREAD_OUT)/*., o os oS)
diff --git a/libc/misc/pthread/tsd.c b/libc/misc/pthread/tsd.c
new file mode 100644
index 000000000..3598b8927
--- /dev/null
+++ b/libc/misc/pthread/tsd.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com>
+ *
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+/* libpthread sets _dl_error_catch_tsd to point to this function.
+ We define it here instead of in libpthread so that it doesn't
+ need to have a TLS segment of its own just for this one pointer. */
+
+#include <features.h>
+
+void **__libc_dl_error_tsd(void) __attribute__ ((const));
+void ** __attribute__ ((const))
+__libc_dl_error_tsd (void)
+{
+ static __thread void *__tsd_data attribute_tls_model_ie;
+ return &__tsd_data;
+}
diff --git a/libc/misc/pthread/unlock.c b/libc/misc/pthread/unlock.c
deleted file mode 100644
index 04de0df58..000000000
--- a/libc/misc/pthread/unlock.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* The weak pthread functions for Linux.
- Copyright (C) 1996, 1997, 1998 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 Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include <pthread.h>
-#include <bits/uClibc_mutex.h>
-
-void attribute_hidden __uclibc_mutex_unlock (void *arg)
-{
- pthread_mutex_t *__mutex = (pthread_mutex_t *)arg;
- __pthread_mutex_unlock(__mutex);
-}
diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c
deleted file mode 100644
index 580c3eb07..000000000
--- a/libc/misc/pthread/weaks.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* The weak pthread functions for Linux.
- Copyright (C) 1996, 1997, 1998 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 Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include <libc-internal.h>
-
-/* Weaks for internal library use only.
- *
- * We need to define weaks here to cover all the pthread functions that
- * libc itself will use so that we aren't forced to link libc against
- * libpthread. This file is only used in libc.a and since we have
- * weaks here, they will be automatically overridden by libpthread.a
- * if it gets linked in.
- */
-
-static int __pthread_return_0 (void) { return 0; }
-static void __pthread_return_void (void) { return; }
-
-weak_alias (__pthread_return_0, __pthread_mutex_init)
-weak_alias (__pthread_return_0, __pthread_mutex_lock)
-weak_alias (__pthread_return_0, __pthread_mutex_trylock)
-weak_alias (__pthread_return_0, __pthread_mutex_unlock)
-weak_alias (__pthread_return_void, _pthread_cleanup_push_defer)
-weak_alias (__pthread_return_void, _pthread_cleanup_pop_restore)
-#ifdef __UCLIBC_HAS_THREADS_NATIVE__
-weak_alias (__pthread_return_0, __pthread_mutexattr_init)
-weak_alias (__pthread_return_0, __pthread_mutexattr_destroy)
-weak_alias (__pthread_return_0, __pthread_mutexattr_settype)
-#endif
diff --git a/libc/misc/regex/Makefile.in b/libc/misc/regex/Makefile.in
index e9d70c596..f95a9f7a3 100644
--- a/libc/misc/regex/Makefile.in
+++ b/libc/misc/regex/Makefile.in
@@ -1,25 +1,24 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-ifeq ($(UCLIBC_HAS_REGEX_OLD),y)
-CSRC := regex_old.c
-else
-CSRC := regex.c
-endif
+subdirs += libc/misc/regex
+
+VARIANT := $(if $(UCLIBC_HAS_REGEX_OLD),_old)
+CSRC-y := regex$(VARIANT).c
MISC_REGEX_DIR := $(top_srcdir)libc/misc/regex
MISC_REGEX_OUT := $(top_builddir)libc/misc/regex
-MISC_REGEX_SRC := $(patsubst %.c,$(MISC_REGEX_DIR)/%.c,$(CSRC))
-MISC_REGEX_OBJ := $(patsubst %.c,$(MISC_REGEX_OUT)/%.o,$(CSRC))
+MISC_REGEX_SRC := $(patsubst %.c,$(MISC_REGEX_DIR)/%.c,$(CSRC-y))
+MISC_REGEX_OBJ := $(patsubst %.c,$(MISC_REGEX_OUT)/%.o,$(CSRC-y))
libc-$(UCLIBC_HAS_REGEX) += $(MISC_REGEX_OBJ)
-objclean-y += misc_regex_objclean
+objclean-y += CLEAN_libc/misc/regex
-misc_regex_objclean:
- $(RM) $(MISC_REGEX_OUT)/*.{o,os}
+CLEAN_libc/misc/regex:
+ $(do_rm) $(addprefix $(MISC_REGEX_OUT)/*., o os)
diff --git a/libc/misc/regex/_regex.h b/libc/misc/regex/_regex.h
deleted file mode 100644
index 01bb21158..000000000
--- a/libc/misc/regex/_regex.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* this file is copied from libc/include/regex.h */
-
-#ifndef _REGEX_H
-#include <regex.h>
-
-/* Document internal interfaces. */
-extern reg_syntax_t __re_set_syntax (reg_syntax_t syntax) attribute_hidden;
-
-extern const char *__re_compile_pattern (const char *pattern, size_t length,
- struct re_pattern_buffer *buffer) attribute_hidden;
-
-extern int __re_compile_fastmap (struct re_pattern_buffer *buffer) attribute_hidden;
-
-extern int __re_search (struct re_pattern_buffer *buffer, const char *string,
- int length, int start, int range,
- struct re_registers *regs) attribute_hidden;
-
-extern int __re_search_2
- (struct re_pattern_buffer *buffer, const char *string1,
- int length1, const char *string2, int length2,
- int start, int range, struct re_registers *regs, int stop) attribute_hidden;
-
-extern int __re_match
- (struct re_pattern_buffer *buffer, const char *string,
- int length, int start, struct re_registers *regs) attribute_hidden;
-
-extern int __re_match_2
- (struct re_pattern_buffer *buffer, const char *string1,
- int length1, const char *string2, int length2,
- int start, struct re_registers *regs, int stop) attribute_hidden;
-
-extern void __re_set_registers
- (struct re_pattern_buffer *buffer, struct re_registers *regs,
- unsigned num_regs, regoff_t *starts, regoff_t *ends) attribute_hidden;
-
-extern int __regcomp (regex_t *__preg, const char *__pattern, int __cflags) attribute_hidden;
-
-extern int __regexec (const regex_t *__preg, const char *__string,
- size_t __nmatch, regmatch_t __pmatch[], int __eflags) attribute_hidden;
-
-extern size_t __regerror (int __errcode, const regex_t *__preg,
- char *__errbuf, size_t __errbuf_size) attribute_hidden;
-
-extern void __regfree (regex_t *__preg) attribute_hidden;
-#endif
diff --git a/libc/misc/regex/regcomp.c b/libc/misc/regex/regcomp.c
index 210ae05ee..dc00109dc 100644
--- a/libc/misc/regex/regcomp.c
+++ b/libc/misc/regex/regcomp.c
@@ -14,9 +14,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
size_t length, reg_syntax_t syntax);
@@ -26,7 +25,7 @@ static void re_compile_fastmap_iter (regex_t *bufp,
static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len);
#ifdef RE_ENABLE_I18N
static void free_charset (re_charset_t *cset);
-#endif /* RE_ENABLE_I18N */
+#endif
static void free_workarea_compile (regex_t *preg);
static reg_errcode_t create_initial_state (re_dfa_t *dfa);
#ifdef RE_ENABLE_I18N
@@ -91,7 +90,7 @@ static reg_errcode_t build_equiv_class (bitset_t sbcset,
re_charset_t *mbcset,
int *equiv_class_alloc,
const unsigned char *name);
-static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
+static reg_errcode_t build_charclass (__RE_TRANSLATE_TYPE trans,
bitset_t sbcset,
re_charset_t *mbcset,
int *char_class_alloc,
@@ -100,13 +99,13 @@ static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
#else /* not RE_ENABLE_I18N */
static reg_errcode_t build_equiv_class (bitset_t sbcset,
const unsigned char *name);
-static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
+static reg_errcode_t build_charclass (__RE_TRANSLATE_TYPE trans,
bitset_t sbcset,
const unsigned char *class_name,
reg_syntax_t syntax);
#endif /* not RE_ENABLE_I18N */
static bin_tree_t *build_charclass_op (re_dfa_t *dfa,
- RE_TRANSLATE_TYPE trans,
+ __RE_TRANSLATE_TYPE trans,
const unsigned char *class_name,
const unsigned char *extra,
int non_match, reg_errcode_t *err);
@@ -126,7 +125,7 @@ static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node);
POSIX doesn't require that we do anything for REG_NOERROR,
but why not be nice? */
-const char __re_error_msgid[] attribute_hidden =
+static const char __re_error_msgid[] =
{
#define REG_NOERROR_IDX 0
gettext_noop ("Success") /* REG_NOERROR */
@@ -180,7 +179,7 @@ const char __re_error_msgid[] attribute_hidden =
gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
};
-const size_t __re_error_msgid_idx[] attribute_hidden =
+static const uint16_t __re_error_msgid_idx[] =
{
REG_NOERROR_IDX,
REG_NOMATCH_IDX,
@@ -211,10 +210,9 @@ const size_t __re_error_msgid_idx[] attribute_hidden =
are set in BUFP on entry. */
const char *
-re_compile_pattern (pattern, length, bufp)
- const char *pattern;
- size_t length;
- struct re_pattern_buffer *bufp;
+re_compile_pattern (const char *pattern,
+ size_t length,
+ struct re_pattern_buffer *bufp)
{
reg_errcode_t ret;
@@ -232,9 +230,6 @@ re_compile_pattern (pattern, length, bufp)
return NULL;
return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_compile_pattern, re_compile_pattern)
-#endif
/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
also be assigned to arbitrarily: each pattern buffer stores its own
@@ -252,21 +247,16 @@ reg_syntax_t re_syntax_options;
defined in regex.h. We return the old syntax. */
reg_syntax_t
-re_set_syntax (syntax)
- reg_syntax_t syntax;
+re_set_syntax (reg_syntax_t syntax)
{
reg_syntax_t ret = re_syntax_options;
re_syntax_options = syntax;
return ret;
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_set_syntax, re_set_syntax)
-#endif
int
-re_compile_fastmap (bufp)
- struct re_pattern_buffer *bufp;
+re_compile_fastmap (struct re_pattern_buffer *bufp)
{
re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
char *fastmap = bufp->fastmap;
@@ -282,9 +272,7 @@ re_compile_fastmap (bufp)
bufp->fastmap_accurate = 1;
return 0;
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_compile_fastmap, re_compile_fastmap)
-#endif
+libc_hidden_def(re_compile_fastmap)
static __inline__ void
__attribute ((always_inline))
@@ -292,7 +280,7 @@ re_set_fastmap (char *fastmap, int icase, int ch)
{
fastmap[ch] = 1;
if (icase)
- fastmap[__tolower (ch)] = 1;
+ fastmap[tolower (ch)] = 1;
}
/* Helper function for re_compile_fastmap.
@@ -355,7 +343,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
if (cset->non_match || cset->ncoll_syms || cset->nequiv_classes
|| cset->nranges || cset->nchar_classes)
{
-# ifdef _LIBC
+# if 0
if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0)
{
/* In this case we want to catch the bytes which are
@@ -375,7 +363,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
for (i = 0; i < SBC_MAX; ++i)
if (__btowc (i) == WEOF)
re_set_fastmap (fastmap, icase, i);
-# endif /* not _LIBC */
+# endif
}
for (i = 0; i < cset->nmbchars; ++i)
{
@@ -396,7 +384,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
else if (type == OP_PERIOD
#ifdef RE_ENABLE_I18N
|| type == OP_UTF8_PERIOD
-#endif /* RE_ENABLE_I18N */
+#endif
|| type == END_OF_RE)
{
memset (fastmap, '\1', sizeof (char) * SBC_MAX);
@@ -444,10 +432,9 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
the return codes and their meanings.) */
int
-regcomp (preg, pattern, cflags)
- regex_t *__restrict preg;
- const char *__restrict pattern;
- int cflags;
+regcomp (regex_t *__restrict preg,
+ const char *__restrict pattern,
+ int cflags)
{
reg_errcode_t ret;
reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED
@@ -498,19 +485,15 @@ regcomp (preg, pattern, cflags)
return (int) ret;
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__regcomp, regcomp)
-#endif
/* Returns a message corresponding to an error code, ERRCODE, returned
from either regcomp or regexec. We don't use PREG here. */
size_t
-regerror (errcode, preg, errbuf, errbuf_size)
- int errcode;
- const regex_t *__restrict preg;
- char *__restrict errbuf;
- size_t errbuf_size;
+regerror (int errcode,
+ const regex_t *__restrict preg,
+ char *__restrict errbuf,
+ size_t errbuf_size)
{
const char *msg;
size_t msg_size;
@@ -532,12 +515,8 @@ regerror (errcode, preg, errbuf, errbuf_size)
{
if (BE (msg_size > errbuf_size, 0))
{
-#if (defined HAVE_MEMPCPY || defined _LIBC) && defined __USE_GNU
- *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
-#else
memcpy (errbuf, msg, errbuf_size - 1);
errbuf[errbuf_size - 1] = 0;
-#endif
}
else
memcpy (errbuf, msg, msg_size);
@@ -545,9 +524,6 @@ regerror (errcode, preg, errbuf, errbuf_size)
return msg_size;
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__regerror, regerror)
-#endif
#ifdef RE_ENABLE_I18N
@@ -614,8 +590,7 @@ free_dfa_content (re_dfa_t *dfa)
/* Free dynamically allocated space used by PREG. */
void
-regfree (preg)
- regex_t *preg;
+regfree (regex_t *preg)
{
re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
if (BE (dfa != NULL, 1))
@@ -629,74 +604,84 @@ regfree (preg)
re_free (preg->translate);
preg->translate = NULL;
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__regfree, regfree)
-#endif
+libc_hidden_def(regfree)
/* Entry points compatible with 4.2 BSD regex library. We don't define
them unless specifically requested. */
-#if defined _REGEX_RE_COMP || defined _LIBC || defined __UCLIBC__
+#if defined _REGEX_RE_COMP || defined __UCLIBC__
/* BSD has one and only one pattern buffer. */
-static struct re_pattern_buffer re_comp_buf;
+static struct re_pattern_buffer *re_comp_buf;
char *
-# if defined _LIBC || defined __UCLIBC__
-/* Make these definitions weak in libc, so POSIX programs can redefine
+/* Make BCD definitions weak in libc, so POSIX programs can redefine
these names if they don't use our functions, and still use
regcomp/regexec above without link errors. */
weak_function
-# endif
-re_comp (s)
- const char *s;
+re_comp (const char *s)
{
reg_errcode_t ret;
- char *fastmap;
- if (!s)
+ /* "If re_comp() is passed NULL or a null string, it returns
+ * without changing the currently compiled regular expression." */
+ if (!s || !s[0])
{
- if (!re_comp_buf.buffer)
+ if (!re_comp_buf)
return gettext ("No previous regular expression");
- return 0;
+ return NULL;
}
- if (re_comp_buf.buffer)
+ if (!re_comp_buf)
{
- fastmap = re_comp_buf.fastmap;
- re_comp_buf.fastmap = NULL;
- __regfree (&re_comp_buf);
- memset (&re_comp_buf, '\0', sizeof (re_comp_buf));
- re_comp_buf.fastmap = fastmap;
+ re_comp_buf = calloc (1, sizeof(*re_comp_buf));
+ if (!re_comp_buf)
+ {
+ ret = REG_ESPACE;
+ goto err;
+ }
}
- if (re_comp_buf.fastmap == NULL)
+ if (re_comp_buf->buffer)
{
- re_comp_buf.fastmap = (char *) malloc (SBC_MAX);
- if (re_comp_buf.fastmap == NULL)
- return (char *) gettext (__re_error_msgid
- + __re_error_msgid_idx[(int) REG_ESPACE]);
+ regfree (re_comp_buf);
+ memset (re_comp_buf, '\0', sizeof(*re_comp_buf));
+ }
+
+ if (re_comp_buf->fastmap == NULL)
+ {
+ re_comp_buf->fastmap = malloc (SBC_MAX);
+ if (re_comp_buf->fastmap == NULL)
+ {
+ ret = REG_ESPACE;
+ goto err;
+ }
}
/* Since `re_exec' always passes NULL for the `regs' argument, we
don't need to initialize the pattern buffer fields which affect it. */
/* Match anchors at newlines. */
- re_comp_buf.newline_anchor = 1;
+ re_comp_buf->newline_anchor = 1;
- ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options);
+ ret = re_compile_internal (re_comp_buf, s, strlen (s), re_syntax_options);
if (!ret)
return NULL;
+ free (re_comp_buf);
+ re_comp_buf = NULL;
+ err:
/* Yes, we're discarding `const' here if !HAVE_LIBINTL. */
return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
}
-#ifdef _LIBC
+#if 0
libc_freeres_fn (free_mem)
{
- __regfree (&re_comp_buf);
+ regfree (re_comp_buf);
+ free (re_comp_buf);
+ re_comp_buf = NULL;
}
#endif
@@ -805,15 +790,11 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
/* Initialize DFA. We use the length of the regular expression PAT_LEN
as the initial length of some arrays. */
-#ifdef __UCLIBC_HAS_WCHAR__
-libc_hidden_proto(_stdlib_mb_cur_max)
-#endif
-
static reg_errcode_t
init_dfa (re_dfa_t *dfa, size_t pat_len)
{
unsigned int table_size;
-#ifndef _LIBC
+#if 1
char *codeset_name;
#endif
@@ -837,12 +818,8 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);
dfa->state_hash_mask = table_size - 1;
-#ifdef __UCLIBC_HAS_WCHAR__
dfa->mb_cur_max = MB_CUR_MAX;
-#else
- dfa->mb_cur_max = 1;
-#endif
-#ifdef _LIBC
+#if 0
if (dfa->mb_cur_max == 6
&& strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
dfa->is_utf8 = 1;
@@ -881,7 +858,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
{
int i, j, ch;
- dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+ dfa->sb_char = calloc (sizeof (bitset_t), 1);
if (BE (dfa->sb_char == NULL, 0))
return REG_ESPACE;
@@ -892,7 +869,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
wint_t wch = __btowc (ch);
if (wch != WEOF)
dfa->sb_char[i] |= (bitset_word_t) 1 << j;
-# ifndef _LIBC
+# if 1
if (isascii (ch) && wch != ch)
dfa->map_notascii = 1;
# endif
@@ -1975,7 +1952,7 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
token->type = CHARACTER;
return 1;
}
-#endif /* RE_ENABLE_I18N */
+#endif
if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS)
&& re_string_cur_idx (input) + 1 < re_string_length (input))
@@ -2553,8 +2530,8 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
I'm not sure, but maybe enough. */
#define BRACKET_NAME_BUF_SIZE 32
-#ifndef _LIBC
- /* Local function for parse_bracket_exp only used in case of NOT _LIBC.
+#if 1
+ /* Local function for parse_bracket_exp only used in case of NOT glibc.
Build the range expression which starts from START_ELEM, and ends
at END_ELEM. The result are written to MBCSET and SBCSET.
RANGE_ALLOC is the allocated size of mbcset->range_starts, and
@@ -2566,10 +2543,10 @@ internal_function
# ifdef RE_ENABLE_I18N
build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc,
bracket_elem_t *start_elem, bracket_elem_t *end_elem)
-# else /* not RE_ENABLE_I18N */
+# else
build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
bracket_elem_t *end_elem)
-# endif /* not RE_ENABLE_I18N */
+# endif
{
unsigned int start_ch, end_ch;
/* Equivalence Classes and Character Classes can't be a range start/end. */
@@ -2611,7 +2588,7 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
return REG_ERANGE;
/* Got valid collation sequence values, add them as a new entry.
- However, for !_LIBC we have no collation elements: if the
+ However, for !glibc we have no collation elements: if the
character set is single byte, the single byte character set
that we build below suffices. parse_bracket_exp passes
no MBCSET if dfa->mb_cur_max == 1. */
@@ -2673,10 +2650,10 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
# endif /* not RE_ENABLE_I18N */
return REG_NOERROR;
}
-#endif /* not _LIBC */
+#endif
-#ifndef _LIBC
-/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..
+#if 1
+/* Helper function for parse_bracket_exp only used in case of NOT glibc.
Build the collating element which is represented by NAME.
The result are written to MBCSET and SBCSET.
COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
@@ -2687,20 +2664,17 @@ internal_function
# ifdef RE_ENABLE_I18N
build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
int *coll_sym_alloc, const unsigned char *name)
-# else /* not RE_ENABLE_I18N */
+# else
build_collating_symbol (bitset_t sbcset, const unsigned char *name)
-# endif /* not RE_ENABLE_I18N */
+# endif
{
size_t name_len = strlen ((const char *) name);
if (BE (name_len != 1, 0))
return REG_ECOLLATE;
- else
- {
- bitset_set (sbcset, name[0]);
- return REG_NOERROR;
- }
+ bitset_set (sbcset, name[0]);
+ return REG_NOERROR;
}
-#endif /* not _LIBC */
+#endif
/* This function parse bracket expression like "[abc]", "[a-c]",
"[[.a-a.]]" etc. */
@@ -2709,7 +2683,7 @@ static bin_tree_t *
parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
reg_syntax_t syntax, reg_errcode_t *err)
{
-#ifdef _LIBC
+#if 0
const unsigned char *collseqmb;
const char *collseqwc;
uint32_t nrules;
@@ -2717,15 +2691,13 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
const int32_t *symb_table;
const unsigned char *extra;
- /* Local function for parse_bracket_exp used in _LIBC environement.
+ /* Local function for parse_bracket_exp used in glibc.
Seek the collating symbol entry correspondings to NAME.
Return the index of the symbol in the SYMB_TABLE. */
auto __inline__ int32_t
__attribute ((always_inline))
- seek_collating_symbol_entry (name, name_len)
- const unsigned char *name;
- size_t name_len;
+ seek_collating_symbol_entry (const unsigned char *name, size_t name_len)
{
int32_t hash = elem_hash ((const char *) name, name_len);
int32_t elem = hash % table_size;
@@ -2755,14 +2727,13 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
return elem;
}
- /* Local function for parse_bracket_exp used in _LIBC environement.
+ /* Local function for parse_bracket_exp used in glibc.
Look up the collation sequence value of BR_ELEM.
Return the value if succeeded, UINT_MAX otherwise. */
auto __inline__ unsigned int
__attribute ((always_inline))
- lookup_collation_sequence_value (br_elem)
- bracket_elem_t *br_elem;
+ lookup_collation_sequence_value (bracket_elem_t *br_elem)
{
if (br_elem->type == SB_CHAR)
{
@@ -2820,7 +2791,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
return UINT_MAX;
}
- /* Local function for parse_bracket_exp used in _LIBC environement.
+ /* Local function for parse_bracket_exp used in glibc.
Build the range expression which starts from START_ELEM, and ends
at END_ELEM. The result are written to MBCSET and SBCSET.
RANGE_ALLOC is the allocated size of mbcset->range_starts, and
@@ -2829,11 +2800,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
auto __inline__ reg_errcode_t
__attribute ((always_inline))
- build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
- re_charset_t *mbcset;
- int *range_alloc;
- bitset_t sbcset;
- bracket_elem_t *start_elem, *end_elem;
+ build_range_exp (re_charset_t *mbcset,
+ int *range_alloc,
+ bitset_t sbcset,
+ bracket_elem_t *start_elem,
+ bracket_elem_t *end_elem)
{
unsigned int ch;
uint32_t start_collseq;
@@ -2904,7 +2875,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
return REG_NOERROR;
}
- /* Local function for parse_bracket_exp used in _LIBC environement.
+ /* Local function for parse_bracket_exp used in glibc.
Build the collating element which is represented by NAME.
The result are written to MBCSET and SBCSET.
COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
@@ -2912,11 +2883,10 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
auto __inline__ reg_errcode_t
__attribute ((always_inline))
- build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
- re_charset_t *mbcset;
- int *coll_sym_alloc;
- bitset_t sbcset;
- const unsigned char *name;
+ build_collating_symbol (re_charset_t *mbcset,
+ int *coll_sym_alloc,
+ bitset_t sbcset,
+ const unsigned char *name)
{
int32_t elem, idx;
size_t name_len = strlen ((const char *) name);
@@ -2978,12 +2948,12 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
re_charset_t *mbcset;
int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
int equiv_class_alloc = 0, char_class_alloc = 0;
-#endif /* not RE_ENABLE_I18N */
+#endif
int non_match = 0;
bin_tree_t *work_tree;
int token_len;
int first_round = 1;
-#ifdef _LIBC
+#if 0
collseqmb = (const unsigned char *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
@@ -3000,15 +2970,15 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
_NL_COLLATE_SYMB_EXTRAMB);
}
#endif
- sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+ sbcset = calloc (sizeof (bitset_t), 1);
#ifdef RE_ENABLE_I18N
- mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-#endif /* RE_ENABLE_I18N */
+ mbcset = calloc (sizeof (re_charset_t), 1);
+#endif
#ifdef RE_ENABLE_I18N
if (BE (sbcset == NULL || mbcset == NULL, 0))
#else
if (BE (sbcset == NULL, 0))
-#endif /* RE_ENABLE_I18N */
+#endif
{
*err = REG_ESPACE;
return NULL;
@@ -3024,7 +2994,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
{
#ifdef RE_ENABLE_I18N
mbcset->non_match = 1;
-#endif /* not RE_ENABLE_I18N */
+#endif
non_match = 1;
if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
bitset_set (sbcset, '\0');
@@ -3104,7 +3074,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
token_len = peek_token_bracket (token, regexp, syntax);
-#ifdef _LIBC
+#if 0
*err = build_range_exp (sbcset, mbcset, &range_alloc,
&start_elem, &end_elem);
#else
@@ -3115,7 +3085,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
# else
*err = build_range_exp (sbcset, &start_elem, &end_elem);
# endif
-#endif /* RE_ENABLE_I18N */
+#endif
if (BE (*err != REG_NOERROR, 0))
goto parse_bracket_exp_free_return;
}
@@ -3149,7 +3119,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
*err = build_equiv_class (sbcset,
#ifdef RE_ENABLE_I18N
mbcset, &equiv_class_alloc,
-#endif /* RE_ENABLE_I18N */
+#endif
start_elem.opr.name);
if (BE (*err != REG_NOERROR, 0))
goto parse_bracket_exp_free_return;
@@ -3158,7 +3128,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
*err = build_collating_symbol (sbcset,
#ifdef RE_ENABLE_I18N
mbcset, &coll_sym_alloc,
-#endif /* RE_ENABLE_I18N */
+#endif
start_elem.opr.name);
if (BE (*err != REG_NOERROR, 0))
goto parse_bracket_exp_free_return;
@@ -3167,7 +3137,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
*err = build_charclass (regexp->trans, sbcset,
#ifdef RE_ENABLE_I18N
mbcset, &char_class_alloc,
-#endif /* RE_ENABLE_I18N */
+#endif
start_elem.opr.name, syntax);
if (BE (*err != REG_NOERROR, 0))
goto parse_bracket_exp_free_return;
@@ -3256,7 +3226,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
re_free (sbcset);
#ifdef RE_ENABLE_I18N
free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
+#endif
return NULL;
}
@@ -3353,11 +3323,11 @@ static reg_errcode_t
#ifdef RE_ENABLE_I18N
build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
int *equiv_class_alloc, const unsigned char *name)
-#else /* not RE_ENABLE_I18N */
+#else
build_equiv_class (bitset_t sbcset, const unsigned char *name)
-#endif /* not RE_ENABLE_I18N */
+#endif
{
-#ifdef _LIBC
+#if 0
uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
if (nrules != 0)
{
@@ -3426,7 +3396,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
}
else
-#endif /* _LIBC */
+#endif
{
if (BE (strlen ((const char *) name) != 1, 0))
return REG_ECOLLATE;
@@ -3443,13 +3413,13 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
static reg_errcode_t
#ifdef RE_ENABLE_I18N
-build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+build_charclass (__RE_TRANSLATE_TYPE trans, bitset_t sbcset,
re_charset_t *mbcset, int *char_class_alloc,
const unsigned char *class_name, reg_syntax_t syntax)
-#else /* not RE_ENABLE_I18N */
-build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+#else
+build_charclass (__RE_TRANSLATE_TYPE trans, bitset_t sbcset,
const unsigned char *class_name, reg_syntax_t syntax)
-#endif /* not RE_ENABLE_I18N */
+#endif
{
int i;
const char *name = (const char *) class_name;
@@ -3525,7 +3495,7 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
}
static bin_tree_t *
-build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
+build_charclass_op (re_dfa_t *dfa, __RE_TRANSLATE_TYPE trans,
const unsigned char *class_name,
const unsigned char *extra, int non_match,
reg_errcode_t *err)
@@ -3534,21 +3504,21 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
#ifdef RE_ENABLE_I18N
re_charset_t *mbcset;
int alloc = 0;
-#endif /* not RE_ENABLE_I18N */
+#endif
reg_errcode_t ret;
re_token_t br_token;
bin_tree_t *tree;
- sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+ sbcset = calloc (sizeof (bitset_t), 1);
#ifdef RE_ENABLE_I18N
- mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-#endif /* RE_ENABLE_I18N */
+ mbcset = calloc (sizeof (re_charset_t), 1);
+#endif
#ifdef RE_ENABLE_I18N
if (BE (sbcset == NULL || mbcset == NULL, 0))
-#else /* not RE_ENABLE_I18N */
+#else
if (BE (sbcset == NULL, 0))
-#endif /* not RE_ENABLE_I18N */
+#endif
{
*err = REG_ESPACE;
return NULL;
@@ -3562,14 +3532,14 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
bitset_set(cset->sbcset, '\0');
*/
mbcset->non_match = 1;
-#endif /* not RE_ENABLE_I18N */
+#endif
}
/* We don't care the syntax in this case. */
ret = build_charclass (trans, sbcset,
#ifdef RE_ENABLE_I18N
mbcset, &alloc,
-#endif /* RE_ENABLE_I18N */
+#endif
class_name, 0);
if (BE (ret != REG_NOERROR, 0))
@@ -3577,7 +3547,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
re_free (sbcset);
#ifdef RE_ENABLE_I18N
free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
+#endif
*err = ret;
return NULL;
}
@@ -3625,13 +3595,13 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
}
#else /* not RE_ENABLE_I18N */
return tree;
-#endif /* not RE_ENABLE_I18N */
+#endif
build_word_op_espace:
re_free (sbcset);
#ifdef RE_ENABLE_I18N
free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
+#endif
*err = REG_ESPACE;
return NULL;
}
@@ -3666,7 +3636,7 @@ static void
free_charset (re_charset_t *cset)
{
re_free (cset->mbchars);
-# ifdef _LIBC
+# if 0
re_free (cset->coll_syms);
re_free (cset->equiv_classes);
re_free (cset->range_starts);
@@ -3746,7 +3716,7 @@ free_token (re_token_t *node)
if (node->type == COMPLEX_BRACKET && node->duplicated == 0)
free_charset (node->opr.mbcset);
else
-#endif /* RE_ENABLE_I18N */
+#endif
if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
re_free (node->opr.sbcset);
}
diff --git a/libc/misc/regex/regex.c b/libc/misc/regex/regex.c
index 10229a265..926ee269e 100644
--- a/libc/misc/regex/regex.c
+++ b/libc/misc/regex/regex.c
@@ -14,84 +14,37 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* uClibc addons */
#include <features.h>
#ifdef __UCLIBC__
-#undef _LIBC
-#define _REGEX_RE_COMP
-#ifdef __USE_GNU
-# define HAVE_MEMPCPY
-#endif
-#define HAVE_LANGINFO
-#define HAVE_LANGINFO_CODESET
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#ifdef __UCLIBC_HAS_WCHAR__
-#define RE_ENABLE_I18N
-#include <wchar.h>
-#include <wctype.h>
-
-#define __iswctype iswctype
-#define __wcrtomb wcrtomb
-#define __btowc btowc
-#define __wctype wctype
-libc_hidden_proto(wcscoll)
-libc_hidden_proto(wcrtomb)
-libc_hidden_proto(mbrtowc)
-libc_hidden_proto(iswctype)
-libc_hidden_proto(iswlower)
-libc_hidden_proto(iswalnum)
-libc_hidden_proto(towlower)
-libc_hidden_proto(towupper)
-libc_hidden_proto(mbsinit)
-libc_hidden_proto(btowc)
-libc_hidden_proto(wctype)
-
-#endif
-
-#include <ctype.h>
-#ifdef __UCLIBC_HAS_CTYPE_TABLES__
-#define __toupper toupper
-#define __tolower tolower
-#endif
-#define __mempcpy mempcpy
-#ifdef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_b_loc)
-libc_hidden_proto(__ctype_toupper_loc)
-#elif defined __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__ctype_b)
-libc_hidden_proto(__ctype_toupper)
-#else
-libc_hidden_proto(isascii)
-#endif
-libc_hidden_proto(toupper)
-libc_hidden_proto(tolower)
-/* Experimentally off - libc_hidden_proto(memcmp) */
-/* Experimentally off - libc_hidden_proto(memcpy) */
-/* Experimentally off - libc_hidden_proto(memmove) */
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(strchr) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-/* Experimentally off - libc_hidden_proto(strncpy) */
-libc_hidden_proto(getenv)
-/* Experimentally off - libc_hidden_proto(strcasecmp) */
-libc_hidden_proto(abort)
-#ifdef __USE_GNU
-/* Experimentally off - libc_hidden_proto(mempcpy) */
-#endif
-
+# define _REGEX_RE_COMP
+# define HAVE_LANGINFO
+# define HAVE_LANGINFO_CODESET
+# include <stdbool.h>
+# include <stdint.h>
+# include <string.h>
+# include <stdlib.h>
+# ifdef __UCLIBC_HAS_WCHAR__
+# define RE_ENABLE_I18N
+# define HAVE_WCHAR_H 1
+# define HAVE_WCRTOMB 1
+# define HAVE_MBRTOWC 1
+# define HAVE_WCSCOLL 1
+# include <wchar.h>
+# define HAVE_WCTYPE_H 1
+# include <wctype.h>
+# define __iswctype iswctype
+# define __wcrtomb wcrtomb
+# define __btowc btowc
+# define __wctype wctype
+# endif
+# include <ctype.h>
+# ifdef __UCLIBC_HAS_LOCALE__
+# define HAVE_LOCALE_H 1
+# endif
#endif
/* Make sure noone compiles this code with a C++ compiler. */
@@ -99,54 +52,14 @@ libc_hidden_proto(abort)
# error "This is C code, use a C compiler"
#endif
-#if defined _LIBC || defined __UCLIBC__
-/* We have to keep the namespace clean. */
-# define regfree(preg) __regfree (preg)
-# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
-# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
-# define regerror(errcode, preg, errbuf, errbuf_size) \
- __regerror(errcode, preg, errbuf, errbuf_size)
-# define re_set_registers(bu, re, nu, st, en) \
- __re_set_registers (bu, re, nu, st, en)
-# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
- __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
-# define re_match(bufp, string, size, pos, regs) \
- __re_match (bufp, string, size, pos, regs)
-# define re_search(bufp, string, size, startpos, range, regs) \
- __re_search (bufp, string, size, startpos, range, regs)
-# define re_compile_pattern(pattern, length, bufp) \
- __re_compile_pattern (pattern, length, bufp)
-# define re_set_syntax(syntax) __re_set_syntax (syntax)
-# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
- __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
-# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
-
-#ifndef __UCLIBC__
-# include "../locale/localeinfo.h"
-#endif
-#endif
-
/* On some systems, limits.h sets RE_DUP_MAX to a lower value than
GNU regex allows. Include it before <regex.h>, which correctly
#undefs RE_DUP_MAX and sets it to the right value. */
#include <limits.h>
-#ifdef __UCLIBC__
-#include "_regex.h"
-#else
#include <regex.h>
-#endif
-#include "regex_internal.h"
+#include "regex_internal.h"
#include "regex_internal.c"
#include "regcomp.c"
#include "regexec.c"
-
-/* Binary backward compatibility. */
-#if _LIBC
-# include <shlib-compat.h>
-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
-link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
-int re_max_failures = 2000;
-# endif
-#endif
diff --git a/libc/misc/regex/regex_internal.c b/libc/misc/regex/regex_internal.c
index 11b1be7c2..c74c6a0c3 100644
--- a/libc/misc/regex/regex_internal.c
+++ b/libc/misc/regex/regex_internal.c
@@ -14,13 +14,12 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
static void re_string_construct_common (const char *str, int len,
re_string_t *pstr,
- RE_TRANSLATE_TYPE trans, int icase,
+ __RE_TRANSLATE_TYPE trans, int icase,
const re_dfa_t *dfa) internal_function;
static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,
const re_node_set *nodes,
@@ -38,7 +37,7 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
static reg_errcode_t
internal_function
re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
- RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
+ __RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
{
reg_errcode_t ret;
int init_buf_len;
@@ -66,7 +65,7 @@ re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
static reg_errcode_t
internal_function
re_string_construct (re_string_t *pstr, const char *str, int len,
- RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
+ __RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
{
reg_errcode_t ret;
memset (pstr, '\0', sizeof (re_string_t));
@@ -109,7 +108,7 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
if (dfa->mb_cur_max > 1)
build_wcs_buffer (pstr);
else
-#endif /* RE_ENABLE_I18N */
+#endif
{
if (trans != NULL)
re_string_translate_buffer (pstr);
@@ -162,7 +161,7 @@ re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
static void
internal_function
re_string_construct_common (const char *str, int len, re_string_t *pstr,
- RE_TRANSLATE_TYPE trans, int icase,
+ __RE_TRANSLATE_TYPE trans, int icase,
const re_dfa_t *dfa)
{
pstr->raw_mbs = (const unsigned char *) str;
@@ -195,7 +194,7 @@ static void
internal_function
build_wcs_buffer (re_string_t *pstr)
{
-#if defined _LIBC || defined __UCLIBC__
+#if defined __UCLIBC__
unsigned char buf[MB_LEN_MAX];
assert (MB_LEN_MAX >= pstr->mb_cur_max);
#else
@@ -266,7 +265,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
mbstate_t prev_st;
int src_idx, byte_idx, end_idx, remain_len;
size_t mbclen;
-#if defined _LIBC || defined __UCLIBC__
+#if defined __UCLIBC__
char buf[MB_LEN_MAX];
assert (MB_LEN_MAX >= pstr->mb_cur_max);
#else
@@ -289,7 +288,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
{
/* In case of a singlebyte character. */
pstr->mbs[byte_idx]
- = __toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
+ = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
/* The next step uses the assumption that wchar_t is encoded
ASCII-safe: all ASCII values can be converted like this. */
pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx];
@@ -523,7 +522,7 @@ build_upper_buffer (re_string_t *pstr)
if (BE (pstr->trans != NULL, 0))
ch = pstr->trans[ch];
if (islower (ch))
- pstr->mbs[char_idx] = __toupper (ch);
+ pstr->mbs[char_idx] = toupper (ch);
else
pstr->mbs[char_idx] = ch;
}
@@ -565,7 +564,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
#ifdef RE_ENABLE_I18N
if (pstr->mb_cur_max > 1)
memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
-#endif /* RE_ENABLE_I18N */
+#endif
pstr->len = pstr->raw_len;
pstr->stop = pstr->raw_stop;
pstr->valid_len = 0;
@@ -596,13 +595,13 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
if (pstr->mb_cur_max > 1)
memmove (pstr->wcs, pstr->wcs + offset,
(pstr->valid_len - offset) * sizeof (wint_t));
-#endif /* RE_ENABLE_I18N */
+#endif
if (BE (pstr->mbs_allocated, 0))
memmove (pstr->mbs, pstr->mbs + offset,
pstr->valid_len - offset);
pstr->valid_len -= offset;
pstr->valid_raw_len -= offset;
-#if DEBUG
+#ifdef DEBUG
assert (pstr->valid_len > 0);
#endif
}
@@ -627,14 +626,14 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
if (pstr->is_utf8)
{
- const unsigned char *raw, *p, *q, *end;
+ const unsigned char *raw, *p, *end;
/* Special case UTF-8. Multi-byte chars start with any
byte other than 0x80 - 0xbf. */
raw = pstr->raw_mbs + pstr->raw_mbs_idx;
end = raw + (offset - pstr->mb_cur_max);
p = raw + offset - 1;
-#ifdef _LIBC
+#if 0
/* We know the wchar_t encoding is UCS4, so for the simple
case, ASCII characters, skip the conversion step. */
if (isascii (*p) && BE (pstr->trans == NULL, 1))
@@ -651,17 +650,8 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
mbstate_t cur_state;
wchar_t wc2;
int mlen = raw + pstr->len - p;
- unsigned char buf[6];
size_t mbclen;
- q = p;
- if (BE (pstr->trans != NULL, 0))
- {
- int i = mlen < 6 ? mlen : 6;
- while (--i >= 0)
- buf[i] = pstr->trans[p[i]];
- q = buf;
- }
/* XXX Don't use mbrtowc, we know which conversion
to use (UTF-8 -> UCS4). */
memset (&cur_state, 0, sizeof (cur_state));
@@ -729,7 +719,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
build_wcs_buffer (pstr);
}
else
-#endif /* RE_ENABLE_I18N */
+#endif
if (BE (pstr->mbs_allocated, 0))
{
if (pstr->icase)
@@ -864,14 +854,11 @@ re_string_context_at (const re_string_t *input, int idx, int eflags)
return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
? CONTEXT_NEWLINE : 0);
}
- else
#endif
- {
- c = re_string_byte_at (input, idx);
- if (bitset_contain (input->word_char, c))
- return CONTEXT_WORD;
- return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;
- }
+ c = re_string_byte_at (input, idx);
+ if (bitset_contain (input->word_char, c))
+ return CONTEXT_WORD;
+ return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;
}
/* Functions for set operation. */
@@ -1068,10 +1055,9 @@ re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
{
if (src1 != NULL && src1->nelem > 0)
return re_node_set_init_copy (dest, src1);
- else if (src2 != NULL && src2->nelem > 0)
+ if (src2 != NULL && src2->nelem > 0)
return re_node_set_init_copy (dest, src2);
- else
- re_node_set_init_empty (dest);
+ re_node_set_init_empty (dest);
return REG_NOERROR;
}
for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
@@ -1197,8 +1183,7 @@ re_node_set_insert (re_node_set *set, int elem)
{
if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1))
return 1;
- else
- return -1;
+ return -1;
}
if (BE (set->nelem, 0) == 0)
@@ -1529,7 +1514,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
reg_errcode_t err;
re_dfastate_t *newstate;
- newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+ newstate = calloc (sizeof (re_dfastate_t), 1);
if (BE (newstate == NULL, 0))
return NULL;
err = re_node_set_init_copy (&newstate->nodes, nodes);
@@ -1544,11 +1529,12 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
{
re_token_t *node = dfa->nodes + nodes->elems[i];
re_token_type_t type = node->type;
+
if (type == CHARACTER && !node->constraint)
continue;
#ifdef RE_ENABLE_I18N
newstate->accept_mb |= node->accept_mb;
-#endif /* RE_ENABLE_I18N */
+#endif
/* If the state has the halt node, the state is a halt state. */
if (type == END_OF_RE)
@@ -1579,7 +1565,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
reg_errcode_t err;
re_dfastate_t *newstate;
- newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+ newstate = calloc (sizeof (re_dfastate_t), 1);
if (BE (newstate == NULL, 0))
return NULL;
err = re_node_set_init_copy (&newstate->nodes, nodes);
diff --git a/libc/misc/regex/regex_internal.h b/libc/misc/regex/regex_internal.h
index 725e33a5a..5d9154fa0 100644
--- a/libc/misc/regex/regex_internal.h
+++ b/libc/misc/regex/regex_internal.h
@@ -14,85 +14,58 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _REGEX_INTERNAL_H
#define _REGEX_INTERNAL_H 1
#include <assert.h>
#include <ctype.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
+#if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET
# include <langinfo.h>
-libc_hidden_proto(nl_langinfo)
#endif
-#if defined HAVE_LOCALE_H || defined _LIBC
+#if defined HAVE_LOCALE_H
# include <locale.h>
#endif
-#if defined HAVE_WCHAR_H || defined _LIBC
+#if defined HAVE_WCHAR_H
# include <wchar.h>
-#endif /* HAVE_WCHAR_H || _LIBC */
-#if defined HAVE_WCTYPE_H || defined _LIBC
+#endif
+#if defined HAVE_WCTYPE_H
# include <wctype.h>
-#endif /* HAVE_WCTYPE_H || _LIBC */
-#if defined HAVE_STDBOOL_H || defined _LIBC
-# include <stdbool.h>
-#endif /* HAVE_STDBOOL_H || _LIBC */
-#if defined HAVE_STDINT_H || defined _LIBC
-# include <stdint.h>
-#endif /* HAVE_STDINT_H || _LIBC */
-#if defined _LIBC
-# include <bits/libc-lock.h>
-#else
-# define __libc_lock_define(CLASS,NAME)
-# define __libc_lock_init(NAME) do { } while (0)
-# define __libc_lock_lock(NAME) do { } while (0)
-# define __libc_lock_unlock(NAME) do { } while (0)
#endif
-
-/* In case that the system doesn't have isblank(). */
-#if !defined _LIBC && !defined HAVE_ISBLANK && !defined isblank && !defined __UCLIBC__
-# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
+#if defined HAVE_STDBOOL_H
+# include <stdbool.h>
#endif
-
-#if defined _LIBC && !defined __UCLIBC__
-# ifndef _RE_DEFINE_LOCALE_FUNCTIONS
-# define _RE_DEFINE_LOCALE_FUNCTIONS 1
-# include <locale/localeinfo.h>
-# include <locale/elem-hash.h>
-# include <locale/coll-lookup.h>
-# endif
+#if defined HAVE_STDINT_H
+# include <stdint.h>
#endif
-/* This is for other GNU distributions with internationalized messages. */
-#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
-# include <libintl.h>
-# ifdef _LIBC
-# undef gettext
-# define gettext(msgid) \
- INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES)
-# endif
+#ifdef __UCLIBC_HAS_THREADS__
+#include <bits/libc-lock.h>
#else
-# define gettext(msgid) (msgid)
+#define __libc_lock_define(CLASS, NAME)
+#define __libc_lock_init(NAME) do { } while (0)
+#define __libc_lock_lock(NAME) do { } while (0)
+#define __libc_lock_unlock(NAME) do { } while (0)
#endif
-#ifndef gettext_noop
-/* This define is so xgettext can find the internationalizable
- strings. */
-# define gettext_noop(String) String
-#endif
+#undef gettext
+#undef gettext_noop
+#define gettext(msgid) (msgid)
+#define gettext_noop(String) String
-#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_WCRTOMB && HAVE_MBRTOWC && HAVE_WCSCOLL) || _LIBC
+#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_WCRTOMB && HAVE_MBRTOWC && HAVE_WCSCOLL)
# define RE_ENABLE_I18N
#endif
#if __GNUC__ >= 3
-# define BE(expr, val) __builtin_expect (expr, val)
+/* uclibc: lean towards smaller size a bit:
+ * OFF: # define BE(expr, val) __builtin_expect (expr, val) */
+# define BE(expr, val) (expr)
#else
# define BE(expr, val) (expr)
# define inline
@@ -107,26 +80,12 @@ libc_hidden_proto(nl_langinfo)
#define NEWLINE_CHAR '\n'
#define WIDE_NEWLINE_CHAR L'\n'
-/* Rename to standard API for using out of glibc. */
-#if !defined _LIBC && !defined __UCLIBC__
-# define __wctype wctype
-# define __iswctype iswctype
-# define __btowc btowc
-# define __mempcpy mempcpy
-# define __wcrtomb wcrtomb
-# define __regfree regfree
-# define attribute_hidden
-#endif /* not _LIBC */
-
#ifdef __GNUC__
# define __attribute(arg) __attribute__ (arg)
#else
# define __attribute(arg)
#endif
-extern const char __re_error_msgid[] attribute_hidden;
-extern const size_t __re_error_msgid_idx[] attribute_hidden;
-
/* An integer used to represent a set of bits. It must be unsigned,
and must be at least as wide as unsigned int. */
typedef unsigned long int bitset_word_t;
@@ -240,23 +199,23 @@ typedef struct
wchar_t *mbchars;
/* Collating symbols. */
-# ifdef _LIBC
+# if 0
int32_t *coll_syms;
# endif
/* Equivalence classes. */
-# ifdef _LIBC
+# if 0
int32_t *equiv_classes;
# endif
/* Range expressions. */
-# ifdef _LIBC
+# if 0
uint32_t *range_starts;
uint32_t *range_ends;
-# else /* not _LIBC */
+# else
wchar_t *range_starts;
wchar_t *range_ends;
-# endif /* not _LIBC */
+# endif
/* Character classes. */
wctype_t *char_classes;
@@ -354,7 +313,7 @@ struct re_string_t
the beginning of the input string. */
unsigned int tip_context;
/* The translation passed as a part of an argument of re_compile_pattern. */
- RE_TRANSLATE_TYPE trans;
+ __RE_TRANSLATE_TYPE trans;
/* Copy of re_dfa_t's word_char. */
re_const_bitset_ptr_t word_char;
/* 1 if REG_ICASE. */
@@ -369,18 +328,9 @@ struct re_string_t
};
typedef struct re_string_t re_string_t;
-
struct re_dfa_t;
typedef struct re_dfa_t re_dfa_t;
-#if !defined _LIBC && !defined __UCLIBC__
-# ifdef __i386__
-# define internal_function __attribute ((regparm (3), stdcall))
-# else
-# define internal_function
-# endif
-#endif
-
static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
int new_buf_len)
internal_function;
@@ -412,8 +362,8 @@ static unsigned int re_string_context_at (const re_string_t *input, int idx,
#include <alloca.h>
-#ifndef _LIBC
-# if HAVE_ALLOCA
+#if 1
+# ifdef HAVE_ALLOCA
/* The OS usually guarantees only one guard page at the bottom of the stack,
and a page size can be as small as 4096 bytes. So we cannot safely
allocate anything larger than 4096 bytes. Also care for the possibility
@@ -557,11 +507,7 @@ typedef struct
{
/* The string object corresponding to the input string. */
re_string_t input;
-#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
- const re_dfa_t *const dfa;
-#else
const re_dfa_t *dfa;
-#endif
/* EFLAGS of the argument of regexec. */
int eflags;
/* Where the matching ends. */
@@ -734,7 +680,7 @@ static int
internal_function __attribute ((pure))
re_string_elem_size_at (const re_string_t *pstr, int idx)
{
-# ifdef _LIBC
+# if 0
const unsigned char *p, *extra;
const int32_t *table, *indirect;
int32_t tmp;
@@ -752,9 +698,8 @@ re_string_elem_size_at (const re_string_t *pstr, int idx)
tmp = findidx (&p);
return p - pstr->mbs - idx;
}
- else
-# endif /* _LIBC */
- return 1;
+# endif
+ return 1;
}
#endif /* RE_ENABLE_I18N */
diff --git a/libc/misc/regex/regex_old.c b/libc/misc/regex/regex_old.c
index a8a8cc79a..fa5de7a28 100644
--- a/libc/misc/regex/regex_old.c
+++ b/libc/misc/regex/regex_old.c
@@ -16,42 +16,29 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/* To exclude some unwanted junk.... */
#undef emacs
#include <features.h>
+/* unistd.h must be included with _LIBC defined: we need smallint */
+#include <unistd.h>
+#include <stdio.h>
#ifdef __UCLIBC__
# undef _LIBC
# define _REGEX_RE_COMP
-# ifdef __USE_GNU
-# define HAVE_MEMPCPY
-# endif
# define STDC_HEADERS
-# define RE_TRANSLATE_TYPE char *
+# define __RE_TRANSLATE_TYPE char *
+# define RE_TRANSLATE_TYPE __RE_TRANSLATE_TYPE
#endif
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
-#include <unistd.h>
-#include <stdio.h>
-
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(memcmp) */
-/* Experimentally off - libc_hidden_proto(memcpy) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-libc_hidden_proto(printf)
-libc_hidden_proto(abort)
-#ifdef __USE_GNU
-/* Experimentally off - libc_hidden_proto(mempcpy) */
-#endif
/* AIX requires this to be the first thing in the file. */
#if defined _AIX && !defined REGEX_MALLOC
- #pragma alloca
+# pragma alloca
#endif
#ifdef HAVE_CONFIG_H
@@ -70,45 +57,16 @@ libc_hidden_proto(abort)
/* For platform which support the ISO C amendement 1 functionality we
support user defined character classes. */
-#if defined __UCLIBC_HAS_WCHAR__
+# if defined __UCLIBC_HAS_WCHAR__
# define WIDE_CHAR_SUPPORT 1
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
# include <wchar.h>
# include <wctype.h>
-libc_hidden_proto(wcslen)
-libc_hidden_proto(mbrtowc)
-libc_hidden_proto(wcrtomb)
-libc_hidden_proto(wcscoll)
-libc_hidden_proto(wctype)
-libc_hidden_proto(iswctype)
-libc_hidden_proto(iswalnum)
-libc_hidden_proto(btowc)
-
# endif
-# if defined _LIBC || defined __UCLIBC__
+# ifdef _LIBC
/* We have to keep the namespace clean. */
-# define regfree(preg) __regfree (preg)
-# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
-# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
-# define regerror(errcode, preg, errbuf, errbuf_size) \
- __regerror(errcode, preg, errbuf, errbuf_size)
-# define re_set_registers(bu, re, nu, st, en) \
- __re_set_registers (bu, re, nu, st, en)
-# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
- __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
-# define re_match(bufp, string, size, pos, regs) \
- __re_match (bufp, string, size, pos, regs)
-# define re_search(bufp, string, size, startpos, range, regs) \
- __re_search (bufp, string, size, startpos, range, regs)
-# define re_compile_pattern(pattern, length, bufp) \
- __re_compile_pattern (pattern, length, bufp)
-# define re_set_syntax(syntax) __re_set_syntax (syntax)
-# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
- __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
-# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
-
-# ifndef __UCLIBC__
+
# define btowc __btowc
/* We are also using some library internals. */
@@ -117,10 +75,9 @@ libc_hidden_proto(btowc)
# include <langinfo.h>
# include <locale/coll-lookup.h>
# endif
-# endif
/* This is for other GNU distributions with internationalized messages. */
-# if HAVE_LIBINTL_H || defined _LIBC
+# if defined HAVE_LIBINTL_H || defined _LIBC
# include <libintl.h>
# ifdef _LIBC
# undef gettext
@@ -208,7 +165,7 @@ char *realloc ();
# endif /* not emacs */
-# if defined _LIBC || HAVE_LIMITS_H
+# if defined _LIBC || defined HAVE_LIMITS_H
# include <limits.h>
# endif
@@ -217,10 +174,8 @@ char *realloc ();
# endif
/* Get the interface, including the syntax bits. */
-# ifdef __UCLIBC__
-# include "_regex.h"
-# endif
# include <regex.h>
+# define translate __REPB_PREFIX(translate)
/* isalpha etc. are used for the character classes. */
# include <ctype.h>
@@ -270,7 +225,7 @@ char *realloc ();
# ifdef _tolower
# define TOLOWER(c) _tolower(c)
# else
-# define TOLOWER(c) __tolower(c)
+# define TOLOWER(c) tolower(c)
# endif
# ifndef NULL
@@ -307,7 +262,7 @@ static void
init_syntax_once (void)
{
register int c;
- static int done = 0;
+ static smallint done = 0;
if (done)
return;
@@ -797,7 +752,7 @@ static smallint debug;
/* Print the fastmap in human-readable form. */
# ifndef DEFINED_ONCE
-void
+static void
print_fastmap (char *fastmap)
{
unsigned was_a_range = 0;
@@ -829,7 +784,7 @@ print_fastmap (char *fastmap)
/* Print a compiled pattern string in human-readable form, starting at
the START pointer into it and ending just before the pointer END. */
-void
+static void
PREFIX(print_partial_compiled_pattern) (UCHAR_T *start, UCHAR_T *end)
{
int mcnt, mcnt2;
@@ -1162,7 +1117,7 @@ PREFIX(print_partial_compiled_pattern) (UCHAR_T *start, UCHAR_T *end)
}
-void
+static void
PREFIX(print_compiled_pattern) (struct re_pattern_buffer *bufp)
{
UCHAR_T *buffer = (UCHAR_T*) bufp->buffer;
@@ -1194,7 +1149,7 @@ PREFIX(print_compiled_pattern) (struct re_pattern_buffer *bufp)
}
-void
+static void
PREFIX(print_double_string) (
const CHAR_T *where,
const CHAR_T *string1,
@@ -1231,7 +1186,7 @@ PREFIX(print_double_string) (
}
}
-# ifndef DEFINED_ONCE
+# if 0 /* ndef DEFINED_ONCE */
void
printchar (int c)
{
@@ -1366,9 +1321,6 @@ re_set_syntax (reg_syntax_t syntax)
# endif /* DEBUG */
return ret;
}
-# if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_set_syntax, re_set_syntax)
-# endif
/* This table gives an error message for each of the error codes listed
in regex.h. Obviously the order here has to be same as there.
@@ -1429,7 +1381,7 @@ static const char re_error_msgid[] =
gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
};
-static const size_t re_error_msgid_idx[] =
+static const uint16_t re_error_msgid_idx[] =
{
REG_NOERROR_IDX,
REG_NOMATCH_IDX,
@@ -1943,7 +1895,7 @@ static boolean PREFIX(at_endline_loc_p) (const CHAR_T *p,
static reg_errcode_t wcs_compile_range (CHAR_T range_start,
const CHAR_T **p_ptr,
const CHAR_T *pend,
- char *translate,
+ __RE_TRANSLATE_TYPE translate,
reg_syntax_t syntax,
UCHAR_T *b,
CHAR_T *char_set);
@@ -1952,7 +1904,7 @@ static void insert_space (int num, CHAR_T *loc, CHAR_T *end);
static reg_errcode_t byte_compile_range (unsigned int range_start,
const char **p_ptr,
const char *pend,
- char *translate,
+ __RE_TRANSLATE_TYPE translate,
reg_syntax_t syntax,
unsigned char *b);
# endif /* WCHAR */
@@ -2091,33 +2043,12 @@ static reg_errcode_t byte_compile_range (unsigned int range_start,
# define MAX_BUF_SIZE (1L << 16)
# define REALLOC(p,s) realloc ((p), (s))
# endif
+# endif /* not DEFINED_ONCE */
/* Extend the buffer by twice its current size via realloc and
reset the pointers that pointed into the old block to point to the
correct places in the new one. If extending the buffer results in it
being larger than MAX_BUF_SIZE, then flag memory exhausted. */
-# if __BOUNDED_POINTERS__
-# define SET_HIGH_BOUND(P) (__ptrhigh (P) = __ptrlow (P) + bufp->allocated)
-# define MOVE_BUFFER_POINTER(P) \
- (__ptrlow (P) += incr, SET_HIGH_BOUND (P), __ptrvalue (P) += incr)
-# define ELSE_EXTEND_BUFFER_HIGH_BOUND \
- else \
- { \
- SET_HIGH_BOUND (b); \
- SET_HIGH_BOUND (begalt); \
- if (fixup_alt_jump) \
- SET_HIGH_BOUND (fixup_alt_jump); \
- if (laststart) \
- SET_HIGH_BOUND (laststart); \
- if (pending_exact) \
- SET_HIGH_BOUND (pending_exact); \
- }
-# else
-# define MOVE_BUFFER_POINTER(P) (P) += incr
-# define ELSE_EXTEND_BUFFER_HIGH_BOUND
-# endif
-# endif /* not DEFINED_ONCE */
-
# ifdef WCHAR
# define EXTEND_BUFFER() \
do { \
@@ -2141,16 +2072,15 @@ static reg_errcode_t byte_compile_range (unsigned int range_start,
if (old_buffer != COMPILED_BUFFER_VAR) \
{ \
int incr = COMPILED_BUFFER_VAR - old_buffer; \
- MOVE_BUFFER_POINTER (b); \
- MOVE_BUFFER_POINTER (begalt); \
+ b += incr; \
+ begalt += incr; \
if (fixup_alt_jump) \
- MOVE_BUFFER_POINTER (fixup_alt_jump); \
+ fixup_alt_jump += incr; \
if (laststart) \
- MOVE_BUFFER_POINTER (laststart); \
+ laststart += incr; \
if (pending_exact) \
- MOVE_BUFFER_POINTER (pending_exact); \
+ pending_exact += incr; \
} \
- ELSE_EXTEND_BUFFER_HIGH_BOUND \
} while (0)
# else /* BYTE */
# define EXTEND_BUFFER() \
@@ -2169,16 +2099,15 @@ static reg_errcode_t byte_compile_range (unsigned int range_start,
if (old_buffer != COMPILED_BUFFER_VAR) \
{ \
int incr = COMPILED_BUFFER_VAR - old_buffer; \
- MOVE_BUFFER_POINTER (b); \
- MOVE_BUFFER_POINTER (begalt); \
+ b += incr; \
+ begalt += incr; \
if (fixup_alt_jump) \
- MOVE_BUFFER_POINTER (fixup_alt_jump); \
+ fixup_alt_jump += incr; \
if (laststart) \
- MOVE_BUFFER_POINTER (laststart); \
+ laststart += incr; \
if (pending_exact) \
- MOVE_BUFFER_POINTER (pending_exact); \
+ pending_exact += incr; \
} \
- ELSE_EXTEND_BUFFER_HIGH_BOUND \
} while (0)
# endif /* WCHAR */
@@ -2253,7 +2182,7 @@ typedef struct
}
# ifndef DEFINED_ONCE
-# if defined _LIBC || WIDE_CHAR_SUPPORT
+# if defined _LIBC || defined WIDE_CHAR_SUPPORT
/* The GNU C library provides support for user-defined character classes
and the functions from ISO C amendement 1. */
# ifdef CHARCLASS_NAME_MAX
@@ -2408,7 +2337,7 @@ PREFIX(regex_compile) (
#endif /* WCHAR */
/* How to translate the characters in the pattern. */
- RE_TRANSLATE_TYPE translate = bufp->translate;
+ __RE_TRANSLATE_TYPE translate = bufp->translate;
/* Address of the count-byte of the most recently inserted `exactn'
command. This makes it possible to tell if a new exact-match
@@ -3309,7 +3238,7 @@ PREFIX(regex_compile) (
the leading `:' and `[' (but set bits for them). */
if (c == ':' && *p == ']')
{
-# if defined _LIBC || WIDE_CHAR_SUPPORT
+# if defined _LIBC || defined WIDE_CHAR_SUPPORT
boolean is_lower = STREQ (str, "lower");
boolean is_upper = STREQ (str, "upper");
wctype_t wt;
@@ -4472,7 +4401,7 @@ static reg_errcode_t
wcs_compile_range (
CHAR_T range_start_char,
const CHAR_T **p_ptr, const CHAR_T *pend,
- RE_TRANSLATE_TYPE translate,
+ __RE_TRANSLATE_TYPE translate,
reg_syntax_t syntax,
CHAR_T *b, CHAR_T *char_set)
{
@@ -4558,14 +4487,14 @@ static reg_errcode_t
byte_compile_range (
unsigned int range_start_char,
const char **p_ptr, const char *pend,
- RE_TRANSLATE_TYPE translate,
+ __RE_TRANSLATE_TYPE translate,
reg_syntax_t syntax,
unsigned char *b)
{
unsigned this_char;
const char *p = *p_ptr;
reg_errcode_t ret;
-# if _LIBC
+# ifdef _LIBC
const unsigned char *collseq;
unsigned int start_colseq;
unsigned int end_colseq;
@@ -4583,7 +4512,7 @@ byte_compile_range (
/* Report an error if the range is empty and the syntax prohibits this. */
ret = syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
-# if _LIBC
+# ifdef _LIBC
collseq = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
_NL_COLLATE_COLLSEQMB);
@@ -4978,13 +4907,10 @@ re_compile_fastmap (struct re_pattern_buffer *bufp)
# ifdef MBS_SUPPORT
if (MB_CUR_MAX != 1)
return wcs_re_compile_fastmap(bufp);
- else
# endif
- return byte_re_compile_fastmap(bufp);
-} /* re_compile_fastmap */
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_compile_fastmap, re_compile_fastmap)
-#endif
+ return byte_re_compile_fastmap(bufp);
+}
+libc_hidden_def(re_compile_fastmap)
/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
@@ -5021,9 +4947,6 @@ re_set_registers (
regs->start = regs->end = (regoff_t *) 0;
}
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_set_registers, re_set_registers)
-#endif
/* Searching routines. */
@@ -5040,9 +4963,7 @@ re_search (
return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
regs, size);
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_search, re_search)
-#endif
+libc_hidden_def(re_search)
/* Using the compiled pattern in BUFP->buffer, first tries to match the
@@ -5080,14 +5001,11 @@ re_search_2 (
if (MB_CUR_MAX != 1)
return wcs_re_search_2 (bufp, string1, size1, string2, size2, startpos,
range, regs, stop);
- else
# endif
- return byte_re_search_2 (bufp, string1, size1, string2, size2, startpos,
- range, regs, stop);
-} /* re_search_2 */
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_search_2, re_search_2)
-#endif
+ return byte_re_search_2 (bufp, string1, size1, string2, size2, startpos,
+ range, regs, stop);
+}
+libc_hidden_def(re_search_2)
#endif /* not INSIDE_RECURSION */
@@ -5141,7 +5059,7 @@ PREFIX(re_search_2) (
{
int val;
register char *fastmap = bufp->fastmap;
- register RE_TRANSLATE_TYPE translate = bufp->translate;
+ register __RE_TRANSLATE_TYPE translate = bufp->translate;
int total_size = size1 + size2;
int endpos = startpos + range;
#ifdef WCHAR
@@ -5543,9 +5461,6 @@ re_match (
# endif
return result;
}
-# if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_match, re_match)
-# endif
#endif /* not emacs */
#endif /* not INSIDE_RECURSION */
@@ -5561,7 +5476,7 @@ static boolean PREFIX(common_op_match_null_string_p) (UCHAR_T **p,
UCHAR_T *end,
PREFIX(register_info_type) *reg_info);
static int PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2,
- int len, char *translate);
+ int len, __RE_TRANSLATE_TYPE translate);
#else /* not INSIDE_RECURSION */
/* re_match_2 matches the compiled pattern in BUFP against the
@@ -5604,9 +5519,6 @@ re_match_2 (
#endif
return result;
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_match_2, re_match_2)
-#endif
#endif /* not INSIDE_RECURSION */
@@ -5724,7 +5636,7 @@ byte_re_match_2_internal (
UCHAR_T *just_past_start_mem = 0;
/* We use this to map every character in the string. */
- RE_TRANSLATE_TYPE translate = bufp->translate;
+ __RE_TRANSLATE_TYPE translate = bufp->translate;
/* Failure point stack. Each place that can handle a failure further
down the line pushes a failure point on this stack. It consists of
@@ -6122,7 +6034,19 @@ byte_re_match_2_internal (
{ /* No. So allocate them with malloc. We need one
extra element beyond `num_regs' for the `-1' marker
GNU code uses. */
- regs->num_regs = MAX (RE_NREGS, num_regs + 1);
+/* regex specs say:
+ * "If REGS_UNALLOCATED, allocate space in the regs structure
+ * for max(RE_NREGS, re_nsub + 1) groups"
+ * but real-world testsuites fail with contrived examples
+ * with lots of groups.
+ * I don't see why we can't just allocate exact needed number.
+ * Incidentally, it makes RE_NREGS unused.
+ *
+ * regs->num_regs = MAX (RE_NREGS, num_regs + 1); - VERY WRONG
+ * regs->num_regs = MIN (RE_NREGS, num_regs + 1); - slightly less wrong
+ * good one which passes uclibc test/regex/tst-regex2.c:
+ */
+ regs->num_regs = num_regs + 1;
regs->start = TALLOC (regs->num_regs, regoff_t);
regs->end = TALLOC (regs->num_regs, regoff_t);
if (regs->start == NULL || regs->end == NULL)
@@ -7287,6 +7211,10 @@ byte_re_match_2_internal (
POP_FAILURE_POINT (sdummy, pdummy,
dummy_low_reg, dummy_high_reg,
reg_dummy, reg_dummy, reg_info_dummy);
+
+ /* Silence 'set but not used' warnings. */
+ (void) pdummy;
+ (void) sdummy;
}
/* Note fall through. */
@@ -7877,7 +7805,7 @@ static int
PREFIX(bcmp_translate) (
const CHAR_T *s1, const CHAR_T *s2,
register int len,
- RE_TRANSLATE_TYPE translate)
+ __RE_TRANSLATE_TYPE translate)
{
register const UCHAR_T *p1 = (const UCHAR_T *) s1;
register const UCHAR_T *p2 = (const UCHAR_T *) s2;
@@ -7910,10 +7838,9 @@ PREFIX(bcmp_translate) (
We call regex_compile to do the actual compilation. */
const char *
-re_compile_pattern (
- const char *pattern,
- size_t length,
- struct re_pattern_buffer *bufp)
+re_compile_pattern (const char *pattern,
+ size_t length,
+ struct re_pattern_buffer *bufp)
{
reg_errcode_t ret;
@@ -7940,9 +7867,6 @@ re_compile_pattern (
return NULL;
return gettext (re_error_msgid + re_error_msgid_idx[(int) ret]);
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_compile_pattern, re_compile_pattern)
-#endif
/* Entry points compatible with 4.2 BSD regex library. We don't define
them unless specifically requested. */
@@ -8081,8 +8005,8 @@ regcomp (
unsigned i;
preg->translate
- = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
- * sizeof (*(RE_TRANSLATE_TYPE)0));
+ = (__RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
+ * sizeof (*(__RE_TRANSLATE_TYPE)0));
if (preg->translate == NULL)
return (int) REG_ESPACE;
@@ -8134,9 +8058,6 @@ regcomp (
return (int) ret;
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__regcomp, regcomp)
-#endif
/* regexec searches for a given pattern, specified by PREG, in the
@@ -8167,7 +8088,8 @@ regexec (
int len = strlen (string);
boolean want_reg_info = !preg->no_sub && nmatch > 0;
- private_preg = *preg;
+ /* use hidden memcpy() ourselves rather than gcc calling public memcpy() */
+ memcpy(&private_preg, preg, sizeof(*preg));
private_preg.not_bol = !!(eflags & REG_NOTBOL);
private_preg.not_eol = !!(eflags & REG_NOTEOL);
@@ -8212,9 +8134,7 @@ regexec (
/* We want zero return to mean success, unlike `re_search'. */
return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__regexec, regexec)
-#endif
+libc_hidden_def(regexec)
/* Returns a message corresponding to an error code, ERRCODE, returned
@@ -8223,7 +8143,7 @@ strong_alias(__regexec, regexec)
size_t
regerror (
int errcode,
- const regex_t *preg,
+ const regex_t * preg attribute_unused,
char *errbuf,
size_t errbuf_size)
{
@@ -8247,12 +8167,8 @@ regerror (
{
if (msg_size > errbuf_size)
{
-#if (defined HAVE_MEMPCPY || defined _LIBC) && defined __USE_GNU
- *((char *) mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
-#else
memcpy (errbuf, msg, errbuf_size - 1);
errbuf[errbuf_size - 1] = 0;
-#endif
}
else
memcpy (errbuf, msg, msg_size);
@@ -8260,9 +8176,6 @@ regerror (
return msg_size;
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__regerror, regerror)
-#endif
/* Free dynamically allocated space used by PREG. */
@@ -8283,9 +8196,7 @@ regfree (regex_t *preg)
free (preg->translate);
preg->translate = NULL;
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__regfree, regfree)
-#endif
+libc_hidden_def(regfree)
#endif /* not emacs */
diff --git a/libc/misc/regex/regexec.c b/libc/misc/regex/regexec.c
index 587e6af30..86bc6b8c5 100644
--- a/libc/misc/regex/regexec.c
+++ b/libc/misc/regex/regexec.c
@@ -14,9 +14,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
int n) internal_function;
@@ -79,7 +78,7 @@ static int sift_states_iter_mb (const re_match_context_t *mctx,
re_sift_context_t *sctx,
int node_idx, int str_idx, int max_str_idx)
internal_function;
-#endif /* RE_ENABLE_I18N */
+#endif
static reg_errcode_t sift_states_backward (const re_match_context_t *mctx,
re_sift_context_t *sctx)
internal_function;
@@ -144,7 +143,7 @@ static re_dfastate_t *transit_state_sb (reg_errcode_t *err,
static reg_errcode_t transit_state_mb (re_match_context_t *mctx,
re_dfastate_t *pstate)
internal_function;
-#endif /* RE_ENABLE_I18N */
+#endif
static reg_errcode_t transit_state_bkref (re_match_context_t *mctx,
const re_node_set *nodes)
internal_function;
@@ -185,12 +184,7 @@ static int build_trtable (const re_dfa_t *dfa,
static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
const re_string_t *input, int idx)
internal_function;
-# ifdef _LIBC
-static unsigned int find_collation_sequence_value (const unsigned char *mbs,
- size_t name_len)
- internal_function;
-# endif /* _LIBC */
-#endif /* RE_ENABLE_I18N */
+#endif
static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
const re_dfastate_t *state,
re_node_set *states_node,
@@ -218,16 +212,12 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx)
We return 0 if we find a match and REG_NOMATCH if not. */
int
-regexec (preg, string, nmatch, pmatch, eflags)
- const regex_t *__restrict preg;
- const char *__restrict string;
- size_t nmatch;
- regmatch_t pmatch[];
- int eflags;
+regexec (const regex_t *__restrict preg, const char *__restrict string,
+ size_t nmatch, regmatch_t pmatch[], int eflags)
{
reg_errcode_t err;
int start, length;
-#ifndef __UCLIBC__ /* libc_lock_lock does not exist */
+#ifdef __UCLIBC_HAS_THREADS__
re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
#endif
@@ -255,28 +245,7 @@ regexec (preg, string, nmatch, pmatch, eflags)
__libc_lock_unlock (dfa->lock);
return err != REG_NOERROR;
}
-
-#ifdef _LIBC
-# include <shlib-compat.h>
-versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
-
-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
-__typeof__ (__regexec) __compat_regexec;
-
-int
-attribute_compat_text_section
-__compat_regexec (const regex_t *__restrict preg,
- const char *__restrict string, size_t nmatch,
- regmatch_t pmatch[], int eflags)
-{
- return regexec (preg, string, nmatch, pmatch,
- eflags & (REG_NOTBOL | REG_NOTEOL));
-}
-compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
-# endif
-#elif defined __UCLIBC__
-strong_alias(__regexec,regexec)
-#endif
+libc_hidden_def(regexec)
/* Entry points for GNU code. */
@@ -308,66 +277,43 @@ strong_alias(__regexec,regexec)
match was found and -2 indicates an internal error. */
int
-re_match (bufp, string, length, start, regs)
- struct re_pattern_buffer *bufp;
- const char *string;
- int length, start;
- struct re_registers *regs;
+re_match (struct re_pattern_buffer *bufp, const char *string, int length,
+ int start, struct re_registers *regs)
{
return re_search_stub (bufp, string, length, start, 0, length, regs, 1);
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_match, re_match)
-#endif
int
-re_search (bufp, string, length, start, range, regs)
- struct re_pattern_buffer *bufp;
- const char *string;
- int length, start, range;
- struct re_registers *regs;
+re_search (struct re_pattern_buffer *bufp, const char *string, int length,
+ int start, int range, struct re_registers *regs)
{
return re_search_stub (bufp, string, length, start, range, length, regs, 0);
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_search, re_search)
-#endif
+libc_hidden_def(re_search)
int
-re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop)
- struct re_pattern_buffer *bufp;
- const char *string1, *string2;
- int length1, length2, start, stop;
- struct re_registers *regs;
+re_match_2 (struct re_pattern_buffer *bufp, const char *string1, int length1,
+ const char *string2, int length2, int start,
+ struct re_registers *regs, int stop)
{
return re_search_2_stub (bufp, string1, length1, string2, length2,
start, 0, regs, stop, 1);
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_match_2, re_match_2)
-#endif
int
-re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop)
- struct re_pattern_buffer *bufp;
- const char *string1, *string2;
- int length1, length2, start, range, stop;
- struct re_registers *regs;
+re_search_2 (struct re_pattern_buffer *bufp, const char *string1, int lenght1,
+ const char *string2, int length2, int start, int range,
+ struct re_registers *regs, int stop)
{
- return re_search_2_stub (bufp, string1, length1, string2, length2,
+ return re_search_2_stub (bufp, string1, lenght1, string2, length2,
start, range, regs, stop, 0);
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_search_2, re_search_2)
-#endif
+libc_hidden_def(re_search_2)
-static int
-re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
- stop, ret_len)
- struct re_pattern_buffer *bufp;
- const char *string1, *string2;
- int length1, length2, start, range, stop, ret_len;
- struct re_registers *regs;
+static int internal_function
+re_search_2_stub (struct re_pattern_buffer *bufp, const char *string1,
+ int length1, const char *string2, int length2, int start,
+ int range, struct re_registers *regs, int stop, int ret_len)
{
const char *str;
int rval;
@@ -385,12 +331,8 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
if (BE (s == NULL, 0))
return -2;
-#if (defined _LIBC || defined __UCLIBC__) && defined __USE_GNU
- memcpy (__mempcpy (s, string1, length1), string2, length2);
-#else
memcpy (s, string1, length1);
memcpy (s + length1, string2, length2);
-#endif
str = s;
free_str = 1;
}
@@ -411,21 +353,18 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
If RET_LEN is nonzero the length of the match is returned (re_match style);
otherwise the position of the match is returned. */
-static int
-re_search_stub (bufp, string, length, start, range, stop, regs, ret_len)
- struct re_pattern_buffer *bufp;
- const char *string;
- int length, start, range, stop, ret_len;
- struct re_registers *regs;
+static int internal_function
+re_search_stub (struct re_pattern_buffer *bufp, const char *string, int length,
+ int start, int range, int stop, struct re_registers *regs,
+ int ret_len)
{
reg_errcode_t result;
regmatch_t *pmatch;
int nregs, rval;
int eflags = 0;
-#ifndef __UCLIBC__ /* libc_lock_lock does not exist */
+#ifdef __UCLIBC_HAS_THREADS__
re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
#endif
-
/* Check for out-of-range. */
if (BE (start < 0 || start > length, 0))
return -1;
@@ -502,11 +441,9 @@ re_search_stub (bufp, string, length, start, range, stop, regs, ret_len)
return rval;
}
-static unsigned
-re_copy_regs (regs, pmatch, nregs, regs_allocated)
- struct re_registers *regs;
- regmatch_t *pmatch;
- int nregs, regs_allocated;
+static unsigned internal_function
+re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, int nregs,
+ int regs_allocated)
{
int rval = REGS_REALLOCATE;
int i;
@@ -572,11 +509,8 @@ re_copy_regs (regs, pmatch, nregs, regs_allocated)
freeing the old data. */
void
-re_set_registers (bufp, regs, num_regs, starts, ends)
- struct re_pattern_buffer *bufp;
- struct re_registers *regs;
- unsigned num_regs;
- regoff_t *starts, *ends;
+re_set_registers (struct re_pattern_buffer *bufp, struct re_registers *regs,
+ unsigned num_regs, regoff_t *starts, regoff_t *ends)
{
if (num_regs)
{
@@ -592,24 +526,18 @@ re_set_registers (bufp, regs, num_regs, starts, ends)
regs->start = regs->end = (regoff_t *) 0;
}
}
-#if defined _LIBC || defined __UCLIBC__
-strong_alias(__re_set_registers, re_set_registers)
-#endif
/* Entry points compatible with 4.2 BSD regex library. We don't define
them unless specifically requested. */
-#if defined _REGEX_RE_COMP || defined _LIBC || defined __UCLIBC__
+#if defined _REGEX_RE_COMP || defined __UCLIBC__
int
-# if defined _LIBC || defined __UCLIBC__
weak_function
-# endif
-re_exec (s)
- const char *s;
+re_exec (const char *s)
{
- return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);
+ return 0 == regexec (re_comp_buf, s, 0, NULL, 0);
}
-#endif /* _REGEX_RE_COMP */
+#endif
/* Internal entry point. */
@@ -621,15 +549,10 @@ re_exec (s)
otherwise return the error code.
Note: We assume front end functions already check ranges.
(START + RANGE >= 0 && START + RANGE <= LENGTH) */
-
-static reg_errcode_t
-re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
- eflags)
- const regex_t *preg;
- const char *string;
- int length, start, range, stop, eflags;
- size_t nmatch;
- regmatch_t pmatch[];
+static reg_errcode_t internal_function
+re_search_internal (const regex_t *preg, const char *string, int length,
+ int start, int range, int stop, size_t nmatch,
+ regmatch_t pmatch[], int eflags)
{
reg_errcode_t err;
const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
@@ -637,19 +560,13 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
int fl_longest_match, match_first, match_kind, match_last = -1;
int extra_nmatch;
int sb, ch;
-#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
- re_match_context_t mctx = { .dfa = dfa };
-#else
re_match_context_t mctx;
-#endif
char *fastmap = (preg->fastmap != NULL && preg->fastmap_accurate
&& range && !preg->can_be_null) ? preg->fastmap : NULL;
- RE_TRANSLATE_TYPE t = preg->translate;
+ __RE_TRANSLATE_TYPE t = preg->translate;
-#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
memset (&mctx, '\0', sizeof (re_match_context_t));
mctx.dfa = dfa;
-#endif
extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0;
nmatch -= extra_nmatch;
@@ -941,9 +858,8 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
return err;
}
-static reg_errcode_t
-prune_impossible_nodes (mctx)
- re_match_context_t *mctx;
+static reg_errcode_t internal_function
+prune_impossible_nodes (re_match_context_t *mctx)
{
const re_dfa_t *const dfa = mctx->dfa;
int halt_node, match_last;
@@ -3435,8 +3351,7 @@ out_free:
character, or we are in a single-byte character set so we can
discern by looking at the character code: allocate a
256-entry transition table. */
- trtable = state->trtable =
- (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
+ trtable = state->trtable = calloc (sizeof (re_dfastate_t *), SBC_MAX);
if (BE (trtable == NULL, 0))
goto out_free;
@@ -3466,8 +3381,7 @@ out_free:
by looking at the character code: build two 256-entry
transition tables, one starting at trtable[0] and one
starting at trtable[SBC_MAX]. */
- trtable = state->word_trtable =
- (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
+ trtable = state->word_trtable = calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
if (BE (trtable == NULL, 0))
goto out_free;
@@ -3797,12 +3711,12 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
if (node->type == COMPLEX_BRACKET)
{
const re_charset_t *cset = node->opr.mbcset;
-# ifdef _LIBC
+# if 0
const unsigned char *pin
= ((const unsigned char *) re_string_get_buffer (input) + str_idx);
int j;
uint32_t nrules;
-# endif /* _LIBC */
+# endif
int match_len = 0;
wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
? re_string_wchar_at (input, str_idx) : 0);
@@ -3825,7 +3739,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
}
}
-# ifdef _LIBC
+# if 0
nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
if (nrules != 0)
{
@@ -3914,15 +3828,13 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
}
}
else
-# endif /* _LIBC */
+# endif
{
/* match with range expression? */
-#if __GNUC__ >= 2
- wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
-#else
- wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
+ wchar_t cmp_buf[6];
+
+ memset (cmp_buf, 0, sizeof(cmp_buf));
cmp_buf[2] = wc;
-#endif
for (i = 0; i < cset->nranges; ++i)
{
cmp_buf[0] = cset->range_starts[i];
@@ -3935,21 +3847,18 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
}
}
}
- check_node_accept_bytes_match:
+
+ check_node_accept_bytes_match:
if (!cset->non_match)
return match_len;
- else
- {
- if (match_len > 0)
- return 0;
- else
- return (elem_len > char_len) ? elem_len : char_len;
- }
+ if (match_len > 0)
+ return 0;
+ return (elem_len > char_len) ? elem_len : char_len;
}
return 0;
}
-# ifdef _LIBC
+# if 0
static unsigned int
internal_function
find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
@@ -4007,7 +3916,7 @@ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
return UINT_MAX;
}
}
-# endif /* _LIBC */
+# endif
#endif /* RE_ENABLE_I18N */
/* Check whether the node accepts the byte which is IDX-th
diff --git a/libc/misc/search/Makefile.in b/libc/misc/search/Makefile.in
index 2da1d6e01..d13766148 100644
--- a/libc/misc/search/Makefile.in
+++ b/libc/misc/search/Makefile.in
@@ -1,33 +1,35 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := hsearch.c
+subdirs += libc/misc/search
+
+CSRC-y := hsearch.c
# multi source _tsearch.c
-CSRC += tsearch.c tfind.c tdelete.c twalk.c tdestroy.c
+CSRC-y += tsearch.c tfind.c tdelete.c twalk.c tdestroy.c
# multi source _lsearch.c
-CSRC += lfind.c lsearch.c
+CSRC-y += lfind.c lsearch.c
# multi source insremque.c
-CSRC += insque.c remque.c
+CSRC-y += insque.c remque.c
# multi source _hsearch_r.c
-CSRC += hcreate_r.c hdestroy_r.c hsearch_r.c
+CSRC-y += hcreate_r.c hdestroy_r.c hsearch_r.c
MISC_SEARCH_DIR := $(top_srcdir)libc/misc/search
MISC_SEARCH_OUT := $(top_builddir)libc/misc/search
-MISC_SEARCH_SRC := $(patsubst %.c,$(MISC_SEARCH_DIR)/%.c,$(CSRC))
-MISC_SEARCH_OBJ := $(patsubst %.c,$(MISC_SEARCH_OUT)/%.o,$(CSRC))
+MISC_SEARCH_SRC := $(patsubst %.c,$(MISC_SEARCH_DIR)/%.c,$(CSRC-y))
+MISC_SEARCH_OBJ := $(patsubst %.c,$(MISC_SEARCH_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_SEARCH_OBJ)
-objclean-y += misc_search_objclean
+objclean-y += CLEAN_libc/misc/search
-misc_search_objclean:
- $(RM) $(MISC_SEARCH_OUT)/*.{o,os}
+CLEAN_libc/misc/search:
+ $(do_rm) $(addprefix $(MISC_SEARCH_OUT)/*., o os)
diff --git a/libc/misc/search/_hsearch_r.c b/libc/misc/search/_hsearch_r.c
index c9c4a9ccf..7b57ce16c 100644
--- a/libc/misc/search/_hsearch_r.c
+++ b/libc/misc/search/_hsearch_r.c
@@ -13,12 +13,11 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <errno.h>
-#include <malloc.h>
+#include <stdlib.h>
#include <string.h>
#include <search.h>
@@ -49,12 +48,12 @@ _ENTRY;
static int isprime (unsigned int number)
{
/* no even number will be passed */
- unsigned int div = 3;
+ unsigned int divisor = 3;
- while (div * div < number && number % div != 0)
- div += 2;
+ while (divisor * divisor < number && number % divisor != 0)
+ divisor += 2;
- return number % div != 0;
+ return number % divisor != 0;
}
@@ -64,7 +63,6 @@ static int isprime (unsigned int number)
indexing as explained in the comment for the hsearch function.
The contents of the table is zeroed, especially the field used
becomes zero. */
-libc_hidden_proto(hcreate_r)
int hcreate_r (size_t nel, struct hsearch_data *htab)
{
/* Test for correct arguments. */
@@ -100,7 +98,6 @@ libc_hidden_def(hcreate_r)
#ifdef L_hdestroy_r
/* After using the hash table it has to be destroyed. The used memory can
be freed and the local static variable can be marked as not used. */
-libc_hidden_proto(hdestroy_r)
void hdestroy_r (struct hsearch_data *htab)
{
/* Test for correct arguments. */
@@ -134,10 +131,7 @@ libc_hidden_def(hdestroy_r)
equality of the stored and the parameter value. This helps to prevent
unnecessary expensive calls of strcmp. */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-libc_hidden_proto(hsearch_r)
int hsearch_r (ENTRY item, ACTION action, ENTRY **retval,
struct hsearch_data *htab)
{
diff --git a/libc/misc/search/_lsearch.c b/libc/misc/search/_lsearch.c
index e91ea9441..0cf496e26 100644
--- a/libc/misc/search/_lsearch.c
+++ b/libc/misc/search/_lsearch.c
@@ -12,7 +12,6 @@
#include <stdio.h>
#include <search.h>
-libc_hidden_proto(lfind)
#ifdef L_lfind
@@ -22,7 +21,7 @@ void *lfind(const void *key, const void *base, size_t *nmemb,
register int n = *nmemb;
while (n--) {
- if ((*compar) (base, key) == 0)
+ if ((*compar) (key, base) == 0)
return ((void*)base);
base += size;
}
@@ -34,7 +33,6 @@ libc_hidden_def(lfind)
#ifdef L_lsearch
-/* Experimentally off - libc_hidden_proto(memcpy) */
void *lsearch(const void *key, void *base, size_t *nmemb,
size_t size, int (*compar)(const void *, const void *))
diff --git a/libc/misc/search/_tsearch.c b/libc/misc/search/_tsearch.c
index 3d43aa543..fe9eedfa9 100644
--- a/libc/misc/search/_tsearch.c
+++ b/libc/misc/search/_tsearch.c
@@ -13,8 +13,7 @@ Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
+not, see <http://www.gnu.org/licenses/>. */
/*
* Tree search generalized from Knuth (6.2.2) Algorithm T just like
@@ -50,8 +49,7 @@ register node **rootp; address of tree root
int (*compar)(); ordering function
*/
-libc_hidden_proto(tsearch)
-void *tsearch(__const void *key, void **vrootp, __compar_fn_t compar)
+void *tsearch(const void *key, void **vrootp, __compar_fn_t compar)
{
register node *q;
register node **rootp = (node **) vrootp;
@@ -81,8 +79,7 @@ libc_hidden_def(tsearch)
#endif
#ifdef L_tfind
-libc_hidden_proto(tfind)
-void *tfind(__const void *key, void * __const *vrootp, __compar_fn_t compar)
+void *tfind(const void *key, void * const *vrootp, __compar_fn_t compar)
{
register node **rootp = (node **) vrootp;
@@ -109,7 +106,7 @@ char *key; key to be deleted
register node **rootp; address of the root of tree
int (*compar)(); comparison function
*/
-void *tdelete(__const void *key, void ** vrootp, __compar_fn_t compar)
+void *tdelete(const void *key, void ** vrootp, __compar_fn_t compar)
{
node *p;
register node *q;
@@ -159,7 +156,7 @@ register node *root; Root of the tree to be walked
register void (*action)(); Function to be called at each node
register int level;
*/
-static void trecurse(__const void *vroot, __action_fn_t action, int level)
+static void trecurse(const void *vroot, __action_fn_t action, int level)
{
register node *root = (node *) vroot;
@@ -182,9 +179,9 @@ node *root; Root of the tree to be walked
void (*action)(); Function to be called at each node
PTR
*/
-void twalk(__const void *vroot, __action_fn_t action)
+void twalk(const void *vroot, __action_fn_t action)
{
- register __const node *root = (node *) vroot;
+ register const node *root = (node *) vroot;
if (root != (node *)0 && action != (__action_fn_t) 0)
trecurse(root, action, 0);
@@ -208,7 +205,6 @@ tdestroy_recurse (node *root, __free_fn_t freefct)
free (root);
}
-libc_hidden_proto(tdestroy)
void tdestroy (void *vroot, __free_fn_t freefct)
{
node *root = (node *) vroot;
diff --git a/libc/misc/search/hsearch.c b/libc/misc/search/hsearch.c
index b1228e2ee..54acfc484 100644
--- a/libc/misc/search/hsearch.c
+++ b/libc/misc/search/hsearch.c
@@ -13,15 +13,11 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <search.h>
-libc_hidden_proto(hdestroy_r)
-libc_hidden_proto(hsearch_r)
-libc_hidden_proto(hcreate_r)
/* The non-reentrant version use a global space for storing the table. */
static struct hsearch_data htab;
diff --git a/libc/misc/search/insremque.c b/libc/misc/search/insremque.c
index 32edf7a4e..99399427e 100644
--- a/libc/misc/search/insremque.c
+++ b/libc/misc/search/insremque.c
@@ -13,8 +13,7 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ see <http://www.gnu.org/licenses/>. */
#include <features.h>
#include <stddef.h>
@@ -27,12 +26,20 @@
void
insque (void *elem, void *prev)
{
- struct qelem *next = ((struct qelem *) prev)->q_forw;
- ((struct qelem *) prev)->q_forw = (struct qelem *) elem;
- if (next != NULL)
- next->q_back = (struct qelem *) elem;
- ((struct qelem *) elem)->q_forw = next;
- ((struct qelem *) elem)->q_back = (struct qelem *) prev;
+ if (prev == NULL)
+ {
+ ((struct qelem *) elem)->q_forw = NULL;
+ ((struct qelem *) elem)->q_back = NULL;
+ }
+ else
+ {
+ struct qelem *next = ((struct qelem *) prev)->q_forw;
+ ((struct qelem *) prev)->q_forw = (struct qelem *) elem;
+ if (next != NULL)
+ next->q_back = (struct qelem *) elem;
+ ((struct qelem *) elem)->q_forw = next;
+ ((struct qelem *) elem)->q_back = (struct qelem *) prev;
+ }
}
#endif
diff --git a/libc/misc/statfs/Makefile.in b/libc/misc/statfs/Makefile.in
index b0a8b84c9..d70ab8f6e 100644
--- a/libc/misc/statfs/Makefile.in
+++ b/libc/misc/statfs/Makefile.in
@@ -1,29 +1,28 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := statvfs.c fstatvfs.c
-ifeq ($(UCLIBC_HAS_LFS),y)
-ifeq ($(UCLIBC_LINUX_SPECIFIC),y)
-CSRC += fstatfs64.c statfs64.c
-endif
-CSRC += statvfs64.c fstatvfs64.c
-endif
+subdirs += libc/misc/statfs
+
+CSRC-y := statvfs.c fstatvfs.c
+CSRC-$(UCLIBC_HAS_LFS) += $(patsubst %.c,%64.c,$(CSRC-y))
+CSRC-$(if $(findstring yy,$(UCLIBC_HAS_LFS)$(UCLIBC_LINUX_SPECIFIC)),y) += \
+ fstatfs64.c statfs64.c
MISC_STATFS_DIR := $(top_srcdir)libc/misc/statfs
MISC_STATFS_OUT := $(top_builddir)libc/misc/statfs
-MISC_STATFS_SRC := $(patsubst %.c,$(MISC_STATFS_DIR)/%.c,$(CSRC))
-MISC_STATFS_OBJ := $(patsubst %.c,$(MISC_STATFS_OUT)/%.o,$(CSRC))
+MISC_STATFS_SRC := $(patsubst %.c,$(MISC_STATFS_DIR)/%.c,$(CSRC-y))
+MISC_STATFS_OBJ := $(patsubst %.c,$(MISC_STATFS_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_STATFS_OBJ)
libc-nomulti-$(UCLIBC_HAS_LFS) += $(MISC_STATFS_OUT)/statvfs64.o $(MISC_STATFS_OUT)/fstatvfs64.o
-objclean-y += misc_statfs_objclean
+objclean-y += CLEAN_libc/misc/statfs
-misc_statfs_objclean:
- $(RM) $(MISC_STATFS_OUT)/*.{o,os,oS}
+CLEAN_libc/misc/statfs:
+ $(do_rm) $(addprefix $(MISC_STATFS_OUT)/*., o os oS)
diff --git a/libc/misc/statfs/fstatfs64.c b/libc/misc/statfs/fstatfs64.c
index a7f94b125..7221a0b79 100644
--- a/libc/misc/statfs/fstatfs64.c
+++ b/libc/misc/statfs/fstatfs64.c
@@ -13,9 +13,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <_lfs_64.h>
@@ -23,18 +22,18 @@
#include <string.h>
#include <sys/statfs.h>
#include <sys/statvfs.h>
+#include <sys/syscall.h>
#include <stddef.h>
-/* Experimentally off - libc_hidden_proto(memcpy) */
-libc_hidden_proto(fstatfs)
+#if defined __NR_fstatfs
+extern __typeof(fstatfs) __libc_fstatfs;
/* Return information about the filesystem on which FD resides. */
-libc_hidden_proto(fstatfs64)
int fstatfs64 (int fd, struct statfs64 *buf)
{
struct statfs buf32;
- if (fstatfs (fd, &buf32) < 0)
+ if (__libc_fstatfs (fd, &buf32) < 0)
return -1;
buf->f_type = buf32.f_type;
@@ -45,9 +44,24 @@ int fstatfs64 (int fd, struct statfs64 *buf)
buf->f_files = buf32.f_files;
buf->f_ffree = buf32.f_ffree;
buf->f_fsid = buf32.f_fsid;
+# ifdef _STATFS_F_FRSIZE
+ buf->f_frsize = buf32.f_frsize;
+# endif
buf->f_namelen = buf32.f_namelen;
memcpy (buf->f_spare, buf32.f_spare, sizeof (buf32.f_spare));
return 0;
}
+#else
+/*
+ * Use the fstatfs64 system call if fstatfs is not defined
+ * This is for backwards compatibility and it should be
+ * made default in the future
+ */
+int fstatfs64(int fd, struct statfs64 *buf)
+{
+ /* Signature has 2 arguments but syscalls wants 3 */
+ return INLINE_SYSCALL(fstatfs64, 3, fd, sizeof(*buf), buf);
+}
+#endif
libc_hidden_def(fstatfs64)
diff --git a/libc/misc/statfs/fstatvfs.c b/libc/misc/statfs/fstatvfs.c
index e21235e01..ff047524f 100644
--- a/libc/misc/statfs/fstatvfs.c
+++ b/libc/misc/statfs/fstatvfs.c
@@ -13,9 +13,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <features.h>
#include <errno.h>
@@ -27,12 +26,6 @@
#include <sys/statfs.h>
#include <sys/statvfs.h>
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strsep) */
-libc_hidden_proto(setmntent)
-libc_hidden_proto(getmntent_r)
-libc_hidden_proto(endmntent)
#ifndef __USE_FILE_OFFSET64
extern int fstatfs (int __fildes, struct statfs *__buf)
@@ -47,9 +40,6 @@ extern int __REDIRECT_NTH (fstatfs, (int __fildes, struct statfs *__buf),
#endif
extern __typeof(fstatfs) __libc_fstatfs;
-libc_hidden_proto(__libc_fstatfs)
-libc_hidden_proto(fstat)
-libc_hidden_proto(stat)
int fstatvfs (int fd, struct statvfs *buf)
{
@@ -66,3 +56,4 @@ int fstatvfs (int fd, struct statvfs *buf)
/* We signal success if the statfs call succeeded. */
return 0;
}
+libc_hidden_def(fstatvfs)
diff --git a/libc/misc/statfs/fstatvfs64.c b/libc/misc/statfs/fstatvfs64.c
index 2d44e4217..e465d76c3 100644
--- a/libc/misc/statfs/fstatvfs64.c
+++ b/libc/misc/statfs/fstatvfs64.c
@@ -13,9 +13,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <_lfs_64.h>
@@ -29,20 +28,8 @@
#include <sys/statvfs.h>
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strsep) */
-libc_hidden_proto(setmntent)
-libc_hidden_proto(getmntent_r)
-libc_hidden_proto(endmntent)
-
#undef stat
#define stat stat64
-#if defined __UCLIBC_LINUX_SPECIFIC__
-libc_hidden_proto(fstatfs64)
-libc_hidden_proto(fstat64)
-#endif
-libc_hidden_proto(stat64)
int fstatvfs64 (int fd, struct statvfs64 *buf)
{
diff --git a/libc/misc/statfs/internal_statvfs.c b/libc/misc/statfs/internal_statvfs.c
index 6075e9cf4..a715d2f58 100644
--- a/libc/misc/statfs/internal_statvfs.c
+++ b/libc/misc/statfs/internal_statvfs.c
@@ -13,14 +13,20 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* The kernel hints us if the f_flags is valid */
+#define ST_VALID 0x0020
/* Now fill in the fields we have information for. */
buf->f_bsize = fsbuf.f_bsize;
- /* Linux does not support f_frsize, so set it to the full block size. */
+#ifdef _STATFS_F_FRSIZE
+ buf->f_frsize = fsbuf.f_frsize;
+#else
+ /* No support for f_frsize so set it to the full block size. */
buf->f_frsize = fsbuf.f_bsize;
+#endif
buf->f_blocks = fsbuf.f_blocks;
buf->f_bfree = fsbuf.f_bfree;
buf->f_bavail = fsbuf.f_bavail;
@@ -28,7 +34,7 @@
buf->f_ffree = fsbuf.f_ffree;
if (sizeof (buf->f_fsid) == sizeof (fsbuf.f_fsid))
buf->f_fsid = (fsbuf.f_fsid.__val[0]
- | ((unsigned long int) fsbuf.f_fsid.__val[1]
+ | ((unsigned long long int) fsbuf.f_fsid.__val[1]
<< (8 * (sizeof (buf->f_fsid)
- sizeof (fsbuf.f_fsid.__val[0])))));
else
@@ -39,10 +45,7 @@
buf->__f_unused = 0;
#endif
buf->f_namemax = fsbuf.f_namelen;
- memset (buf->__f_spare, '\0', 6 * sizeof (int));
-
- /* What remains to do is to fill the fields f_favail and f_flag. */
-
+ memset (buf->__f_spare, '\0', sizeof(buf->__f_spare));
/* XXX I have no idea how to compute f_favail. Any idea??? */
buf->f_favail = buf->f_ffree;
@@ -51,61 +54,63 @@
file. The way we can test for matching filesystem is using the
device number. */
buf->f_flag = 0;
- if (STAT (&st) >= 0)
- {
- int save_errno = errno;
- struct mntent mntbuf;
- FILE *mtab;
-
- mtab = setmntent ("/proc/mounts", "r");
- if (mtab == NULL)
- mtab = setmntent (_PATH_MOUNTED, "r");
+ if (STAT (&st) >= 0
+#ifdef _STATFS_F_FLAGS
+ && (fsbuf.f_flags & ST_VALID) == 0
+#endif
+ ) {
+ int save_errno = errno;
+ struct mntent mntbuf;
+ FILE *mtab;
- if (mtab != NULL)
- {
- char tmpbuf[1024];
+ mtab = setmntent ("/proc/mounts", "r");
+ if (mtab == NULL)
+ mtab = setmntent (_PATH_MOUNTED, "r");
+ if (mtab != NULL) {
+ char tmpbuf[1024];
- while (getmntent_r (mtab, &mntbuf, tmpbuf, sizeof (tmpbuf)))
- {
- struct stat fsst;
+ while (getmntent_r (mtab, &mntbuf, tmpbuf, sizeof (tmpbuf))) {
+ struct stat fsst;
- /* Find out about the device the current entry is for. */
- if (stat (mntbuf.mnt_dir, &fsst) >= 0
- && st.st_dev == fsst.st_dev)
- {
- /* Bingo, we found the entry for the device FD is on.
- Now interpret the option string. */
- char *cp = mntbuf.mnt_opts;
- char *opt;
+ /* Find out about the device the current entry is for. */
+ if (stat (mntbuf.mnt_dir, &fsst) >= 0
+ && st.st_dev == fsst.st_dev) {
+ /* Bingo, we found the entry for the device FD is on.
+ Now interpret the option string. */
+ char *cp = mntbuf.mnt_opts;
+ char *opt;
- while ((opt = strsep (&cp, ",")) != NULL)
- if (strcmp (opt, "ro") == 0)
- buf->f_flag |= ST_RDONLY;
- else if (strcmp (opt, "nosuid") == 0)
- buf->f_flag |= ST_NOSUID;
+ while ((opt = strsep (&cp, ",")) != NULL)
+ if (strcmp (opt, "ro") == 0)
+ buf->f_flag |= ST_RDONLY;
+ else if (strcmp (opt, "nosuid") == 0)
+ buf->f_flag |= ST_NOSUID;
#ifdef __USE_GNU
- else if (strcmp (opt, "noexec") == 0)
- buf->f_flag |= ST_NOEXEC;
- else if (strcmp (opt, "nodev") == 0)
- buf->f_flag |= ST_NODEV;
- else if (strcmp (opt, "sync") == 0)
- buf->f_flag |= ST_SYNCHRONOUS;
- else if (strcmp (opt, "mand") == 0)
- buf->f_flag |= ST_MANDLOCK;
- else if (strcmp (opt, "noatime") == 0)
- buf->f_flag |= ST_NOATIME;
- else if (strcmp (opt, "nodiratime") == 0)
- buf->f_flag |= ST_NODIRATIME;
+ else if (strcmp (opt, "noexec") == 0)
+ buf->f_flag |= ST_NOEXEC;
+ else if (strcmp (opt, "nodev") == 0)
+ buf->f_flag |= ST_NODEV;
+ else if (strcmp (opt, "sync") == 0)
+ buf->f_flag |= ST_SYNCHRONOUS;
+ else if (strcmp (opt, "mand") == 0)
+ buf->f_flag |= ST_MANDLOCK;
+ else if (strcmp (opt, "noatime") == 0)
+ buf->f_flag |= ST_NOATIME;
+ else if (strcmp (opt, "nodiratime") == 0)
+ buf->f_flag |= ST_NODIRATIME;
+ else if (strcmp (opt, "relatime") == 0)
+ buf->f_flag |= ST_RELATIME;
#endif
-
- /* We can stop looking for more entries. */
- break;
+ /* We can stop looking for more entries. */
+ break;
+ }
}
- }
-
- /* Close the file. */
- endmntent (mtab);
- }
-
- __set_errno (save_errno);
- }
+ /* Close the file. */
+ endmntent (mtab);
+ }
+ __set_errno (save_errno);
+ }
+#ifdef _STATFS_F_FLAGS
+ else
+ buf->f_flag = fsbuf.f_flags ^ ST_VALID;
+#endif
diff --git a/libc/misc/statfs/statfs64.c b/libc/misc/statfs/statfs64.c
index 18ce33be8..b1a33b790 100644
--- a/libc/misc/statfs/statfs64.c
+++ b/libc/misc/statfs/statfs64.c
@@ -13,27 +13,25 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <_lfs_64.h>
#include <string.h>
#include <stddef.h>
#include <sys/statfs.h>
+#include <sys/syscall.h>
+extern __typeof(statfs) __libc_statfs;
-/* Experimentally off - libc_hidden_proto(memcpy) */
-libc_hidden_proto(statfs)
-
+#if defined __NR_statfs
/* Return information about the filesystem on which FILE resides. */
-libc_hidden_proto(statfs64)
int statfs64 (const char *file, struct statfs64 *buf)
{
struct statfs buf32;
- if (statfs (file, &buf32) < 0)
+ if (__libc_statfs (file, &buf32) < 0)
return -1;
buf->f_type = buf32.f_type;
@@ -45,8 +43,21 @@ int statfs64 (const char *file, struct statfs64 *buf)
buf->f_ffree = buf32.f_ffree;
buf->f_fsid = buf32.f_fsid;
buf->f_namelen = buf32.f_namelen;
+#ifdef _STATFS_F_FRSIZE
+ buf->f_frsize = buf32.f_frsize;
+#endif
+#ifdef _STATFS_F_FLAGS
+ buf->f_flags = buf32.f_flags;
+#endif
memcpy (buf->f_spare, buf32.f_spare, sizeof (buf32.f_spare));
return 0;
}
+#else
+int statfs64 (const char *file, struct statfs64 *buf)
+{
+ return INLINE_SYSCALL(statfs64, 3, file, sizeof(*buf), buf);
+}
+#endif
+
libc_hidden_def(statfs64)
diff --git a/libc/misc/statfs/statvfs.c b/libc/misc/statfs/statvfs.c
index 0feb8731d..dcd10f7af 100644
--- a/libc/misc/statfs/statvfs.c
+++ b/libc/misc/statfs/statvfs.c
@@ -13,9 +13,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <features.h>
#include <errno.h>
@@ -27,16 +26,8 @@
#include <sys/statfs.h>
#include <sys/statvfs.h>
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strsep) */
-libc_hidden_proto(setmntent)
-libc_hidden_proto(getmntent_r)
-libc_hidden_proto(endmntent)
extern __typeof(statfs) __libc_statfs;
-libc_hidden_proto(__libc_statfs)
-libc_hidden_proto(stat)
int statvfs (const char *file, struct statvfs *buf)
{
@@ -53,3 +44,4 @@ int statvfs (const char *file, struct statvfs *buf)
/* We signal success if the statfs call succeeded. */
return 0;
}
+libc_hidden_def(statvfs)
diff --git a/libc/misc/statfs/statvfs64.c b/libc/misc/statfs/statvfs64.c
index 008ba78c9..b02fc6bbe 100644
--- a/libc/misc/statfs/statvfs64.c
+++ b/libc/misc/statfs/statvfs64.c
@@ -13,9 +13,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <_lfs_64.h>
@@ -28,21 +27,9 @@
#include <sys/statfs.h>
#include <sys/statvfs.h>
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strsep) */
-libc_hidden_proto(setmntent)
-libc_hidden_proto(getmntent_r)
-libc_hidden_proto(endmntent)
#undef stat
#define stat stat64
-#if defined __UCLIBC_LINUX_SPECIFIC__
-libc_hidden_proto(statfs64)
-#else
-libc_hidden_proto(statvfs)
-#endif
-libc_hidden_proto(stat64)
int statvfs64 (const char *file, struct statvfs64 *buf)
{
diff --git a/libc/misc/syslog/Makefile.in b/libc/misc/syslog/Makefile.in
index 8355ac0cd..2d00a33fd 100644
--- a/libc/misc/syslog/Makefile.in
+++ b/libc/misc/syslog/Makefile.in
@@ -1,23 +1,25 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := syslog.c
+subdirs += libc/misc/syslog
+
+CSRC-y := syslog.c
MISC_SYSLOG_DIR := $(top_srcdir)libc/misc/syslog
MISC_SYSLOG_OUT := $(top_builddir)libc/misc/syslog
-MISC_SYSLOG_SRC := $(patsubst %.c,$(MISC_SYSLOG_DIR)/%.c,$(CSRC))
-MISC_SYSLOG_OBJ := $(patsubst %.c,$(MISC_SYSLOG_OUT)/%.o,$(CSRC))
+MISC_SYSLOG_SRC := $(patsubst %.c,$(MISC_SYSLOG_DIR)/%.c,$(CSRC-y))
+MISC_SYSLOG_OBJ := $(patsubst %.c,$(MISC_SYSLOG_OUT)/%.o,$(CSRC-y))
ifeq ($(UCLIBC_HAS_SYSLOG),y)
libc-y += $(MISC_SYSLOG_OBJ)
endif
-objclean-y += misc_syslog_objclean
+objclean-y += CLEAN_libc/misc/syslog
-misc_syslog_objclean:
- $(RM) $(MISC_SYSLOG_OUT)/*.{o,os}
+CLEAN_libc/misc/syslog:
+ $(do_rm) $(addprefix $(MISC_SYSLOG_OUT)/*., o os)
diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c
index c90703ab8..1df0d1ae3 100644
--- a/libc/misc/syslog/syslog.c
+++ b/libc/misc/syslog/syslog.c
@@ -58,8 +58,6 @@
* - Major code cleanup.
*/
-#define __FORCE_GLIBC
-#include <features.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
@@ -79,46 +77,26 @@
#include <ctype.h>
#include <signal.h>
-libc_hidden_proto(openlog)
-libc_hidden_proto(syslog)
-libc_hidden_proto(vsyslog)
-libc_hidden_proto(closelog)
-
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(memcpy) */
-/* Experimentally off - libc_hidden_proto(memmove) */
-/* Experimentally off - libc_hidden_proto(strchr) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-/* Experimentally off - libc_hidden_proto(strncpy) */
-libc_hidden_proto(open)
-libc_hidden_proto(fcntl)
-libc_hidden_proto(socket)
-libc_hidden_proto(close)
-libc_hidden_proto(write)
-libc_hidden_proto(getpid)
-libc_hidden_proto(ctime)
-libc_hidden_proto(sigaction)
-libc_hidden_proto(sigemptyset)
-libc_hidden_proto(connect)
-libc_hidden_proto(sprintf)
-libc_hidden_proto(vsnprintf)
-/* Experimentally off - libc_hidden_proto(time) */
#include <bits/uClibc_mutex.h>
-__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+
+/* !glibc_compat: glibc uses argv[0] by default
+ * (default: if there was no openlog or if openlog passed NULL),
+ * not string "syslog"
+ */
+static const char *LogTag = "syslog"; /* string to tag the entry with */
static int LogFile = -1; /* fd for log */
static smalluint connected; /* have done connect */
-/* all bits in option argument for openlog() fit in 8 bits */
-static smalluint LogStat = 0; /* status bits, set by openlog() */
-static const char *LogTag = "syslog"; /* string to tag the entry with */
-/* this fits in 8 bits too (LOG_LOCAL7 = 23<<3 = 184),
- * but NB: LOG_FACMASK is bigger (= 0x03f8 = 127<<3) for some strange reason.
- * Oh well. */
-static int LogFacility = LOG_USER;/* default facility code */
-/* bits mask of priorities (eight prios - 8 bits is enough) */
-static smalluint LogMask = 0xff; /* mask of priorities to be logged */
+/* all bits in option argument for openlog fit in 8 bits */
+static smalluint LogStat = 0; /* status bits, set by openlog */
+/* default facility code if openlog is not called */
+/* (this fits in 8 bits even without >> 3 shift, but playing extra safe) */
+static smalluint LogFacility = LOG_USER >> 3;
+/* bits mask of priorities to be logged (eight prios - 8 bits is enough) */
+static smalluint LogMask = 0xff;
/* AF_UNIX address of local logger (we use struct sockaddr
* instead of struct sockaddr_un since "/dev/log" is small enough) */
static const struct sockaddr SyslogAddr = {
@@ -138,45 +116,42 @@ closelog_intern(int sig)
if (sig == 0) { /* called from closelog()? - reset to defaults */
LogStat = 0;
LogTag = "syslog";
- LogFacility = LOG_USER;
+ LogFacility = LOG_USER >> 3;
LogMask = 0xff;
}
}
-/*
- * OPENLOG -- open system log
- */
-void
-openlog(const char *ident, int logstat, int logfac)
+static void
+openlog_intern(void)
{
+ int fd;
int logType = SOCK_DGRAM;
-
- __UCLIBC_MUTEX_LOCK(mylock);
-
- if (ident != NULL)
- LogTag = ident;
- LogStat = logstat;
- if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
- LogFacility = logfac;
- if (LogFile == -1) {
-retry:
- if (LogStat & LOG_NDELAY) {
- if ((LogFile = socket(AF_UNIX, logType, 0)) == -1) {
- goto DONE;
+ static const struct timeval tv = { 1, 0 };
+
+ fd = LogFile;
+ if (fd == -1) {
+ retry:
+ if (1) { /* if statement left in to make .diff cleaner */
+ LogFile = fd = socket(AF_UNIX, logType, 0);
+ if (fd == -1) {
+ return;
}
- fcntl(LogFile, F_SETFD, 1); /* 1 == FD_CLOEXEC */
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
/* We don't want to block if e.g. syslogd is SIGSTOPed */
- fcntl(LogFile, F_SETFL, O_NONBLOCK | fcntl(LogFile, F_GETFL));
+ fcntl(fd, F_SETFL, O_NONBLOCK | fcntl(fd, F_GETFL));
}
}
- if (LogFile != -1 && !connected) {
- if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) != -1) {
+ 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 (LogFile != -1) {
- close(LogFile);
- LogFile = -1;
+ if (fd != -1) {
+ close(fd);
+ LogFile = fd = -1;
}
if (logType == SOCK_DGRAM) {
logType = SOCK_STREAM;
@@ -184,18 +159,40 @@ retry:
}
}
}
+}
+
+/*
+ * OPENLOG -- open system log
+ */
+void
+openlog(const char *ident, int logstat, int logfac)
+{
+ __UCLIBC_MUTEX_LOCK(mylock);
+
+ 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();
-DONE:
__UCLIBC_MUTEX_UNLOCK(mylock);
}
-libc_hidden_def(openlog)
/*
* syslog, vsyslog --
* print message on log file; output is intended for syslogd(8).
*/
+static
+#ifndef __USE_BSD
+__always_inline
+#endif
void
-vsyslog(int pri, const char *fmt, va_list ap)
+__vsyslog(int pri, const char *fmt, va_list ap)
{
register char *p;
char *last_chr, *head_end, *end, *stdp;
@@ -203,29 +200,24 @@ vsyslog(int pri, const char *fmt, va_list ap)
int fd, saved_errno;
int rc;
char tbuf[1024]; /* syslogd is unable to handle longer messages */
- struct sigaction action, oldaction;
- memset(&action, 0, sizeof(action));
- action.sa_handler = closelog_intern;
- sigemptyset(&action.sa_mask); /* TODO: memset already zeroed it out! */
- /* Only two errors are possible for sigaction:
- * EFAULT (bad address of &oldaction) and EINVAL (invalid signo)
- * none of which can happen here. */
- /*int sigpipe =*/ sigaction(SIGPIPE, &action, &oldaction);
+ /* Just throw out this message if pri has bad bits. */
+ if ((pri & ~(LOG_PRIMASK|LOG_FACMASK)) != 0)
+ return;
saved_errno = errno;
__UCLIBC_MUTEX_LOCK(mylock);
- /* See if we should just throw out this message. */
- if (!(LogMask & LOG_MASK(LOG_PRI(pri))) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
+ /* See if we should just throw out this message according to LogMask. */
+ if ((LogMask & LOG_MASK(LOG_PRI(pri))) == 0)
goto getout;
if (LogFile < 0 || !connected)
- openlog(LogTag, LogStat | LOG_NDELAY, 0);
+ openlog_intern();
/* Set default facility if none specified. */
if ((pri & LOG_FACMASK) == 0)
- pri |= LogFacility;
+ pri |= ((int)LogFacility << 3);
/* Build the message. We know the starting part of the message can take
* no longer than 64 characters plus length of the LogTag. So it's
@@ -233,7 +225,7 @@ vsyslog(int pri, const char *fmt, va_list ap)
*/
(void)time(&now);
stdp = p = tbuf + sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);
- if (LogTag) {
+ /*if (LogTag) - always true */ {
if (strlen(LogTag) < sizeof(tbuf) - 64)
p += sprintf(p, "%s", LogTag);
else
@@ -241,7 +233,7 @@ vsyslog(int pri, const char *fmt, va_list ap)
}
if (LogStat & LOG_PID)
p += sprintf(p, "[%d]", getpid());
- if (LogTag) {
+ /*if (LogTag) - always true */ {
*p++ = ':';
*p++ = ' ';
}
@@ -280,14 +272,24 @@ 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;
+ *last_chr = '\0';
+ retry:
if (LogFile >= 0) {
do {
- rc = write(LogFile, p, last_chr + 1 - p);
+ /* 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;
}
@@ -315,12 +317,12 @@ vsyslog(int pri, const char *fmt, va_list ap)
(void)close(fd);
}
-getout:
+ getout:
__UCLIBC_MUTEX_UNLOCK(mylock);
- /*if (sigpipe == 0)*/
- sigaction(SIGPIPE, &oldaction, (struct sigaction *) NULL);
}
-libc_hidden_def(vsyslog)
+#ifdef __USE_BSD
+strong_alias(__vsyslog,vsyslog)
+#endif
void
syslog(int pri, const char *fmt, ...)
@@ -328,7 +330,7 @@ syslog(int pri, const char *fmt, ...)
va_list ap;
va_start(ap, fmt);
- vsyslog(pri, fmt, ap);
+ __vsyslog(pri, fmt, ap);
va_end(ap);
}
libc_hidden_def(syslog)
@@ -343,7 +345,6 @@ closelog(void)
closelog_intern(0); /* 0: reset LogXXX globals to default */
__UCLIBC_MUTEX_UNLOCK(mylock);
}
-libc_hidden_def(closelog)
/* setlogmask -- set the log mask level */
int setlogmask(int pmask)
@@ -352,9 +353,9 @@ int setlogmask(int pmask)
omask = LogMask;
if (pmask != 0) {
- __UCLIBC_MUTEX_LOCK(mylock);
+/* __UCLIBC_MUTEX_LOCK(mylock);*/
LogMask = pmask;
- __UCLIBC_MUTEX_UNLOCK(mylock);
+/* __UCLIBC_MUTEX_UNLOCK(mylock);*/
}
return omask;
}
diff --git a/libc/misc/sysvipc/Makefile.in b/libc/misc/sysvipc/Makefile.in
index 6b88ad6f0..d1c124430 100644
--- a/libc/misc/sysvipc/Makefile.in
+++ b/libc/misc/sysvipc/Makefile.in
@@ -1,30 +1,32 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := ftok.c __syscall_ipc.c
+subdirs += libc/misc/sysvipc
+
+CSRC-y := ftok.c __syscall_ipc.c
# multi source sem.c
-CSRC += semget.c semctl.c semop.c semtimedop.c
+CSRC-y += semget.c semctl.c semop.c semtimedop.c
# multi source shm.c
-CSRC += shmat.c shmctl.c shmdt.c shmget.c
+CSRC-y += shmat.c shmctl.c shmdt.c shmget.c
# multi source msgq.c
-CSRC += msgctl.c msgget.c msgrcv.c msgsnd.c
+CSRC-y += msgctl.c msgget.c msgrcv.c msgsnd.c
MISC_SYSVIPC_DIR := $(top_srcdir)libc/misc/sysvipc
MISC_SYSVIPC_OUT := $(top_builddir)libc/misc/sysvipc
-MISC_SYSVIPC_SRC := $(patsubst %.c,$(MISC_SYSVIPC_DIR)/%.c,$(CSRC))
-MISC_SYSVIPC_OBJ := $(patsubst %.c,$(MISC_SYSVIPC_OUT)/%.o,$(CSRC))
+MISC_SYSVIPC_SRC := $(patsubst %.c,$(MISC_SYSVIPC_DIR)/%.c,$(CSRC-y))
+MISC_SYSVIPC_OBJ := $(patsubst %.c,$(MISC_SYSVIPC_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_SYSVIPC_OBJ)
-objclean-y += misc_sysvipc_objclean
+objclean-y += CLEAN_libc/misc/sysvipc
-misc_sysvipc_objclean:
- $(RM) $(MISC_SYSVIPC_OUT)/*.{o,os}
+CLEAN_libc/misc/sysvipc:
+ $(do_rm) $(addprefix $(MISC_SYSVIPC_OUT)/*., o os)
diff --git a/libc/misc/sysvipc/__syscall_ipc.c b/libc/misc/sysvipc/__syscall_ipc.c
index 99dfbf49f..304a42c29 100644
--- a/libc/misc/sysvipc/__syscall_ipc.c
+++ b/libc/misc/sysvipc/__syscall_ipc.c
@@ -13,5 +13,5 @@
#define __NR___syscall_ipc __NR_ipc
#include "ipc.h"
_syscall6(int, __syscall_ipc, unsigned int, call, long, first, long, second, long,
- third, void *, ptr, void *, fifth);
+ third, void *, ptr, void *, fifth)
#endif
diff --git a/libc/misc/sysvipc/ftok.c b/libc/misc/sysvipc/ftok.c
index 12627cad1..1e7549984 100644
--- a/libc/misc/sysvipc/ftok.c
+++ b/libc/misc/sysvipc/ftok.c
@@ -14,20 +14,22 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ see <http://www.gnu.org/licenses/>. */
#include <sys/ipc.h>
#include <sys/stat.h>
-
-libc_hidden_proto(stat)
+#ifdef __UCLIBC_HAS_LFS__
+# include <_lfs_64.h>
+#else
+# define stat64 stat
+#endif
key_t ftok (const char *pathname, int proj_id)
{
- struct stat st;
+ struct stat64 st;
key_t key;
- if (stat(pathname, &st) < 0)
+ if (stat64(pathname, &st) < 0)
return (key_t) -1;
key = ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16)
diff --git a/libc/misc/sysvipc/ipc.h b/libc/misc/sysvipc/ipc.h
index 339d1364b..b342dc1cf 100644
--- a/libc/misc/sysvipc/ipc.h
+++ b/libc/misc/sysvipc/ipc.h
@@ -3,10 +3,14 @@
#include <syscall.h>
#include <bits/wordsize.h>
-#if __WORDSIZE == 32 || defined __alpha__ || defined __mips__
-# define __IPC_64 0x100
+#ifndef __ARCH_HAS_DEPRECATED_SYSCALLS__
+# define __IPC_64 0x0
#else
-# define __IPC_64 0x0
+# if __WORDSIZE == 32 || defined __alpha__ || defined __mips__
+# define __IPC_64 0x100
+# else
+# define __IPC_64 0x0
+# endif
#endif
#ifdef __NR_ipc
diff --git a/libc/misc/sysvipc/msgq.c b/libc/misc/sysvipc/msgq.c
index d83ed2208..185cd268b 100644
--- a/libc/misc/sysvipc/msgq.c
+++ b/libc/misc/sysvipc/msgq.c
@@ -1,13 +1,18 @@
#include <errno.h>
#include <sys/msg.h>
#include "ipc.h"
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include "sysdep-cancel.h"
+#else
+#define SINGLE_THREAD_P 1
+#endif
#ifdef L_msgctl
#ifdef __NR_msgctl
#define __NR___libc_msgctl __NR_msgctl
-static __inline__ _syscall3(int, __libc_msgctl, int, msqid, int, cmd, struct msqid_ds *, buf);
+static __inline__ _syscall3(int, __libc_msgctl, int, msqid, int, cmd, struct msqid_ds *, buf)
#endif
/* Message queue control operation. */
int msgctl(int msqid, int cmd, struct msqid_ds *buf)
@@ -43,31 +48,65 @@ struct new_msg_buf{
#ifdef L_msgrcv
#ifdef __NR_msgrcv
-_syscall5(int, msgrcv, int, msqid, void *, msgp, size_t, msgsz, long int, msgtyp, int, msgflg);
-#else
-int msgrcv (int msqid, void *msgp, size_t msgsz,
- long int msgtyp, int msgflg)
+#define __NR___syscall_msgrcv __NR_msgrcv
+static inline _syscall5(ssize_t, __syscall_msgrcv, int, msqid, void *, msgp,
+ size_t, msgsz, long int, msgtyp, int, msgflg)
+#endif
+static inline ssize_t do_msgrcv (int msqid, void *msgp, size_t msgsz,
+ long int msgtyp, int msgflg)
{
+#ifdef __NR_msgrcv
+ return __syscall_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
+#else
struct new_msg_buf temp;
temp.r_msgtyp = msgtyp;
temp.oldmsg = msgp;
return __syscall_ipc(IPCOP_msgrcv ,msqid ,msgsz ,msgflg ,&temp, 0);
+#endif
}
+ssize_t msgrcv (int msqid, void *msgp, size_t msgsz,
+ long int msgtyp, int msgflg)
+{
+ if (SINGLE_THREAD_P)
+ return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ int oldtype = LIBC_CANCEL_ASYNC ();
+ int result = do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
+ LIBC_CANCEL_RESET (oldtype);
+ return result;
#endif
+}
#endif
#ifdef L_msgsnd
#ifdef __NR_msgsnd
-_syscall4(int, msgsnd, int, msqid, const void *, msgp, size_t, msgsz, int, msgflg);
-#else
+#define __NR___syscall_msgsnd __NR_msgsnd
+static inline _syscall4(int, __syscall_msgsnd, int, msqid, const void *, msgp,
+ size_t, msgsz, int, msgflg)
+#endif
/* Send message to message queue. */
-int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
+static inline int do_msgsnd (int msqid, const void *msgp, size_t msgsz,
+ int msgflg)
{
+#ifdef __NR_msgsnd
+ return __syscall_msgsnd(msqid, msgp, msgsz, msgflg);
+#else
return __syscall_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg, (void *)msgp, 0);
+#endif
}
+int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
+{
+ if (SINGLE_THREAD_P)
+ return do_msgsnd(msqid, msgp, msgsz, msgflg);
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ int oldtype = LIBC_CANCEL_ASYNC ();
+ int result = do_msgsnd(msqid, msgp, msgsz, msgflg);
+ LIBC_CANCEL_RESET (oldtype);
+ return result;
#endif
+}
#endif
diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c
index 1caec5a8c..64be1cae0 100644
--- a/libc/misc/sysvipc/sem.c
+++ b/libc/misc/sysvipc/sem.c
@@ -14,12 +14,13 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ see <http://www.gnu.org/licenses/>. */
#include <errno.h>
#include <sys/sem.h>
#include <stddef.h>
+#include <stdlib.h> /* for NULL */
+
#include "ipc.h"
@@ -27,7 +28,6 @@
/* Return identifier for array of NSEMS semaphores associated with
KEY. */
#include <stdarg.h>
-#include <stdlib.h>
/* arg for semctl system calls. */
union semun {
int val; /* value for SETVAL */
@@ -40,7 +40,7 @@ union semun {
#ifdef __NR_semctl
#define __NR___semctl __NR_semctl
-static __inline__ _syscall4(int, __semctl, int, semid, int, semnum, int, cmd, void *, arg);
+static __inline__ _syscall4(int, __semctl, int, semid, int, semnum, int, cmd, void *, arg)
#endif
int semctl(int semid, int semnum, int cmd, ...)
@@ -61,11 +61,8 @@ int semctl(int semid, int semnum, int cmd, ...)
#endif
#ifdef L_semget
-/* for definition of NULL */
-#include <stdlib.h>
-
#ifdef __NR_semget
-_syscall3(int, semget, key_t, key, int, nsems, int, semflg);
+_syscall3(int, semget, key_t, key, int, nsems, int, semflg)
#else
/* Return identifier for array of NSEMS semaphores associated
@@ -80,7 +77,7 @@ int semget (key_t key, int nsems, int semflg)
#ifdef L_semop
#ifdef __NR_semop
-_syscall3(int, semop, int, semid, struct sembuf *, sops, size_t, nsops);
+_syscall3(int, semop, int, semid, struct sembuf *, sops, size_t, nsops)
#else
/* Perform user-defined atomical operation of array of semaphores. */
@@ -94,14 +91,14 @@ int semop (int semid, struct sembuf *sops, size_t nsops)
#ifdef L_semtimedop
#ifdef __NR_semtimedop
-_syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout);
+_syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
#else
int semtimedop(int semid, struct sembuf *sops, size_t nsops,
const struct timespec *timeout)
{
- return __syscall_ipc(IPCOP_semtimedop, semid, nsops, 0, sops, timeout);
+ return __syscall_ipc(IPCOP_semtimedop, semid, nsops, 0, sops, (void *) timeout);
}
#endif
#endif
diff --git a/libc/misc/sysvipc/shm.c b/libc/misc/sysvipc/shm.c
index b1af943b8..cd46ff0dd 100644
--- a/libc/misc/sysvipc/shm.c
+++ b/libc/misc/sysvipc/shm.c
@@ -14,8 +14,7 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ see <http://www.gnu.org/licenses/>. */
/* SHMLBA uses it on most of the archs (not mips) */
#define __getpagesize getpagesize
@@ -34,11 +33,10 @@
# define __NR_shmat __NR_osf_shmat
#endif
#ifdef __NR_shmat
-_syscall3(void *, shmat, int, shmid, const void *,shmaddr, int, shmflg);
+_syscall3(void *, shmat, int, shmid, const void *,shmaddr, int, shmflg)
#else
/* psm: don't remove this, else mips will fail */
#include <unistd.h>
-libc_hidden_proto(getpagesize)
void * shmat (int shmid, const void *shmaddr, int shmflg)
{
@@ -55,13 +53,13 @@ void * shmat (int shmid, const void *shmaddr, int shmflg)
#ifdef L_shmctl
/* Provide operations to control over shared memory segments. */
#ifdef __NR_shmctl
-#define __NR___libc_shmctl __NR_shmctl
-static __inline__ _syscall3(int, __libc_shmctl, int, shmid, int, cmd, struct shmid_ds *, buf);
+#define __NR___syscall_shmctl __NR_shmctl
+static __always_inline _syscall3(int, __syscall_shmctl, int, shmid, int, cmd, struct shmid_ds *, buf)
#endif
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
{
#ifdef __NR_shmctl
- return __libc_shmctl(shmid, cmd | __IPC_64, buf);
+ return __syscall_shmctl(shmid, cmd | __IPC_64, buf);
#else
return __syscall_ipc(IPCOP_shmctl, shmid, cmd | __IPC_64, 0, buf, 0);
#endif
@@ -73,7 +71,7 @@ int shmctl(int shmid, int cmd, struct shmid_ds *buf)
/* Detach shared memory segment starting at address specified by SHMADDR
from the caller's data segment. */
#ifdef __NR_shmdt
-_syscall1(int, shmdt, const void *, shmaddr);
+_syscall1(int, shmdt, const void *, shmaddr)
#else
int shmdt (const void *shmaddr)
{
@@ -86,7 +84,7 @@ int shmdt (const void *shmaddr)
/* Return an identifier for an shared memory segment of at least size SIZE
which is associated with KEY. */
#ifdef __NR_shmget
-_syscall3(int, shmget, key_t, key, size_t, size, int, shmflg);
+_syscall3(int, shmget, key_t, key, size_t, size, int, shmflg)
#else
int shmget (key_t key, size_t size, int shmflg)
{
diff --git a/libc/misc/time/Makefile.in b/libc/misc/time/Makefile.in
index 4c4d510b1..906a1b28e 100644
--- a/libc/misc/time/Makefile.in
+++ b/libc/misc/time/Makefile.in
@@ -1,41 +1,34 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := adjtime.c
-ifeq ($(UCLIBC_SUSV3_LEGACY),y)
-CSRC += ftime.c
-endif
+subdirs += libc/misc/time
+
+CSRC-y := adjtime.c
+CSRC-$(UCLIBC_SUSV3_LEGACY) += ftime.c
# multi source time.c
-CSRC += asctime.c asctime_r.c clock.c ctime.c ctime_r.c gmtime.c gmtime_r.c \
+CSRC-y += asctime.c asctime_r.c clock.c ctime.c ctime_r.c gmtime.c gmtime_r.c \
localtime.c localtime_r.c mktime.c strftime.c strptime.c tzset.c \
_time_t2tm.c __time_tm.c _time_mktime.c dysize.c timegm.c \
_time_mktime_tzi.c _time_localtime_tzi.c
-ifeq ($(UCLIBC_HAS_FLOATS),y)
-CSRC += difftime.c
-endif
-ifeq ($(UCLIBC_HAS_XLOCALE),y)
-CSRC += strftime_l.c strptime_l.c
-endif
-ifeq ($(UCLIBC_HAS_WCHAR),y)
-CSRC += wcsftime.c
-ifeq ($(UCLIBC_HAS_XLOCALE),y)
-CSRC += wcsftime_l.c
-endif
-endif
+CSRC-$(UCLIBC_HAS_FLOATS) += difftime.c
+CSRC-$(UCLIBC_HAS_XLOCALE) += strftime_l.c strptime_l.c
+CSRC-$(UCLIBC_HAS_WCHAR) += wcsftime.c
+CSRC-$(if $(findstring yy,$(UCLIBC_HAS_WCHAR)$(UCLIBC_HAS_XLOCALE)),y) += \
+ wcsftime_l.c
MISC_TIME_DIR := $(top_srcdir)libc/misc/time
MISC_TIME_OUT := $(top_builddir)libc/misc/time
-MISC_TIME_SRC := $(patsubst %.c,$(MISC_TIME_DIR)/%.c,$(CSRC))
-MISC_TIME_OBJ := $(patsubst %.c,$(MISC_TIME_OUT)/%.o,$(CSRC))
+MISC_TIME_SRC := $(patsubst %.c,$(MISC_TIME_DIR)/%.c,$(CSRC-y))
+MISC_TIME_OBJ := $(patsubst %.c,$(MISC_TIME_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_TIME_OBJ)
-objclean-y += misc_time_objclean
+objclean-y += CLEAN_libc/misc/time
-misc_time_objclean:
- $(RM) $(MISC_TIME_OUT)/*.{o,os}
+CLEAN_libc/misc/time:
+ $(do_rm) $(addprefix $(MISC_TIME_OUT)/*., o os)
diff --git a/libc/misc/time/adjtime.c b/libc/misc/time/adjtime.c
index cfa94339a..1e8087104 100644
--- a/libc/misc/time/adjtime.c
+++ b/libc/misc/time/adjtime.c
@@ -9,7 +9,6 @@
#include <sys/timex.h>
#include <errno.h>
-libc_hidden_proto(adjtimex)
#define MAX_SEC (LONG_MAX / 1000000L - 2)
#define MIN_SEC (LONG_MIN / 1000000L + 2)
diff --git a/libc/misc/time/ftime.c b/libc/misc/time/ftime.c
index 49c137ce5..c6c460594 100644
--- a/libc/misc/time/ftime.c
+++ b/libc/misc/time/ftime.c
@@ -12,22 +12,22 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <sys/timeb.h>
#include <sys/time.h>
-libc_hidden_proto(gettimeofday)
int ftime(struct timeb *timebuf)
{
struct timeval tv;
struct timezone tz;
- if (gettimeofday (&tv, &tz) < 0)
- return -1;
+ /* In Linux, gettimeofday fails only on bad parameter.
+ * We know that here parameters aren't bad.
+ */
+ gettimeofday (&tv, &tz);
timebuf->time = tv.tv_sec;
timebuf->millitm = (tv.tv_usec + 999) / 1000;
diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c
index ed135c580..03635d86d 100644
--- a/libc/misc/time/time.c
+++ b/libc/misc/time/time.c
@@ -146,46 +146,24 @@
#include <bits/uClibc_uintmaxtostr.h>
#include <bits/uClibc_mutex.h>
-
-#ifdef __UCLIBC_HAS_WCHAR__
+#if defined __UCLIBC_HAS_WCHAR__ && (defined L_wcsftime || defined L_wcsftime_l)
#include <wchar.h>
-#endif
-#ifdef __UCLIBC_HAS_XLOCALE__
-#include <xlocale.h>
-#endif
-
-libc_hidden_proto(asctime)
-libc_hidden_proto(asctime_r)
-libc_hidden_proto(ctime)
-libc_hidden_proto(localtime)
-libc_hidden_proto(localtime_r)
-
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(memcpy) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strcpy) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-/* Experimentally off - libc_hidden_proto(strncpy) */
-/* libc_hidden_proto(sprintf) */
-libc_hidden_proto(open)
-libc_hidden_proto(read)
-libc_hidden_proto(close)
-libc_hidden_proto(getenv)
-libc_hidden_proto(tzset)
-libc_hidden_proto(gettimeofday)
-/* Experimentally off - libc_hidden_proto(strncasecmp) */
-libc_hidden_proto(strtol)
-libc_hidden_proto(strtoul)
-libc_hidden_proto(nl_langinfo)
-
-#ifdef __UCLIBC_HAS_XLOCALE__
-/* Experimentally off - libc_hidden_proto(strncasecmp_l) */
-libc_hidden_proto(strtol_l)
-libc_hidden_proto(strtoul_l)
-libc_hidden_proto(nl_langinfo_l)
-libc_hidden_proto(__ctype_b_loc)
-#elif defined __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__ctype_b)
+# define CHAR_T wchar_t
+# define UCHAR_T unsigned int
+# ifdef L_wcsftime
+# define strftime wcsftime
+# define L_strftime
+# if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
+# define strftime_l wcsftime_l
+# endif
+# endif
+# ifdef L_wcsftime_l
+# define strftime_l wcsftime_l
+# define L_strftime_l
+# endif
+#else
+# define CHAR_T char
+# define UCHAR_T unsigned char
#endif
#ifndef __isleap
@@ -246,7 +224,7 @@ typedef struct {
char tzname[TZNAME_MAX+1];
} rule_struct;
-__UCLIBC_MUTEX_EXTERN(_time_tzlock);
+__UCLIBC_MUTEX_EXTERN(_time_tzlock) attribute_hidden;
extern rule_struct _time_tzinfo[2] attribute_hidden;
@@ -308,7 +286,7 @@ libc_hidden_def(asctime)
* If we take the implicit assumption as given, then the implementation below
* is still incorrect for tm_year values < -900, as there will be either
* 0-padding and/or a missing negative sign for the year conversion . But given
- * the ususal use of asctime(), I think it isn't unreasonable to restrict correct
+ * the usual use of asctime(), I think it isn't unreasonable to restrict correct
* operation to the domain of years between 1000 and 9999.
*/
@@ -406,16 +384,16 @@ char *asctime_r(register const struct tm *__restrict ptm,
if (((unsigned int) tmp) >= 100) { /* Just check 2 digit non-neg. */
buffer[-1] = *buffer = '?';
} else
-#else /* SAFE_ASCTIME_R */
+#else
assert(((unsigned int) tmp) < 100); /* Just check 2 digit non-neg. */
-#endif /* SAFE_ASCTIME_R */
+#endif
{
*buffer = '0' + (tmp % 10);
#ifdef __BCC__
buffer[-1] = '0' + (tmp/10);
-#else /* __BCC__ */
+#else
buffer[-1] += (tmp/10);
-#endif /* __BCC__ */
+#endif
}
} while ((buffer -= 2)[-2] == '0');
@@ -433,8 +411,6 @@ libc_hidden_def(asctime_r)
#include <sys/times.h>
-libc_hidden_proto(times)
-
#ifndef __BCC__
#if CLOCKS_PER_SEC != 1000000L
#error unexpected value for CLOCKS_PER_SEC!
@@ -501,8 +477,23 @@ clock_t clock(void)
char *ctime(const time_t *t)
{
- /* ANSI/ISO/SUSv3 say that ctime is equivalent to the following. */
- return asctime(localtime(t));
+ /* ANSI/ISO/SUSv3 say that ctime is equivalent to the following:
+ * return asctime(localtime(t));
+ * I don't think "equivalent" means "it uses the same internal buffer",
+ * it means "gives the same resultant string".
+ *
+ * I doubt anyone ever uses weird code like:
+ * struct tm *ptm = localtime(t1); ...; ctime(t2); use(ptm);
+ * which relies on the assumption that ctime's and localtime's
+ * internal static struct tm is the same.
+ *
+ * Using localtime_r instead of localtime avoids linking in
+ * localtime's static buffer:
+ */
+ struct tm xtm;
+ memset(&xtm, 0, sizeof(xtm));
+
+ return asctime(localtime_r(t, &xtm));
}
libc_hidden_def(ctime)
#endif
@@ -531,7 +522,7 @@ double difftime(time_t time1, time_t time0)
#if (LONG_MAX >> DBL_MANT_DIG) == 0
/* time_t fits in the mantissa of a double. */
- return ((double) time1) - time0;
+ return (double)time1 - (double)time0;
#elif ((LONG_MAX >> DBL_MANT_DIG) >> DBL_MANT_DIG) == 0
@@ -618,43 +609,48 @@ libc_hidden_def(localtime_r)
#ifdef __UCLIBC_HAS_TM_EXTENSIONS__
-/* Experimentally off - libc_hidden_proto(strnlen) */
-
struct ll_tzname_item;
typedef struct ll_tzname_item {
struct ll_tzname_item *next;
- char tzname[TZNAME_MAX+1];
+ char tzname[1];
} ll_tzname_item_t;
-static ll_tzname_item_t ll_tzname[] = {
- { ll_tzname + 1, "UTC" }, /* Always 1st. */
- { NULL, "???" } /* Always 2nd. (invalid or out-of-memory) */
-};
+/* Structures form a list "UTC" -> "???" -> "tzname1" -> "tzname2"... */
+static struct {
+ struct ll_tzname_item *next;
+ char tzname[4];
+} ll_tzname_UNKNOWN = { NULL, "???" };
+static const struct {
+ struct ll_tzname_item *next;
+ char tzname[4];
+} ll_tzname_UTC = { (void*)&ll_tzname_UNKNOWN, "UTC" };
static const char *lookup_tzname(const char *key)
{
- ll_tzname_item_t *p;
+ int len;
+ ll_tzname_item_t *p = (void*) &ll_tzname_UTC;
- for (p=ll_tzname ; p ; p=p->next) {
- if (!strcmp(p->tzname, key)) {
+ do {
+ if (strcmp(p->tzname, key) == 0)
return p->tzname;
- }
- }
+ p = p->next;
+ } while (p != NULL);
/* Hmm... a new name. */
- if (strnlen(key, TZNAME_MAX+1) < TZNAME_MAX+1) { /* Verify legal length */
- if ((p = malloc(sizeof(ll_tzname_item_t))) != NULL) {
+ len = strnlen(key, TZNAME_MAX+1);
+ if (len < TZNAME_MAX+1) { /* Verify legal length */
+ p = malloc(sizeof(ll_tzname_item_t) + len);
+ if (p != NULL) {
/* Insert as 3rd item in the list. */
- p->next = ll_tzname[1].next;
- ll_tzname[1].next = p;
- strcpy(p->tzname, key);
- return p->tzname;
+ p->next = ll_tzname_UNKNOWN.next;
+ ll_tzname_UNKNOWN.next = p;
+ return strcpy(p->tzname, key);
}
}
/* Either invalid or couldn't alloc. */
- return ll_tzname[1].tzname;
+ return ll_tzname_UNKNOWN.tzname;
}
#endif /* __UCLIBC_HAS_TM_EXTENSIONS__ */
@@ -687,7 +683,7 @@ static int tm_isdst(register const struct tm *__restrict ptm,
isleap = __isleap(i);
--i;
day0 = (1
- + i /* Normal years increment 1 wday. */
+ + i /* Normal years increment 1 wday. */
+ (i/4)
- (i/100)
+ (i/400) ) % 7;
@@ -700,20 +696,22 @@ static int tm_isdst(register const struct tm *__restrict ptm,
}
} else if (r->rule_type == 'M') {
/* Find 0-based day number for 1st of the month. */
- day = 31*r->month - day_cor[r->month -1];
+ day = 31 * r->month - day_cor[r->month - 1];
if (isleap && (day >= 59)) {
++day;
}
- monlen = 31 + day_cor[r->month -1] - day_cor[r->month];
- if (isleap && (r->month > 1)) {
+ monlen = 31 + day_cor[r->month - 1] - day_cor[r->month];
+ if (isleap && (r->month == 2)) {
++monlen;
}
- /* Wweekday (0 is Sunday) of 1st of the month
+ /* Weekday (0 is Sunday) of 1st of the month
* is (day0 + day) % 7. */
- if ((mday = r->day - ((day0 + day) % 7)) >= 0) {
- mday -= 7; /* Back up into prev month since r->week>0. */
+ mday = r->day - ((day0 + day) % 7);
+ if (mday >= 0) {
+ mday -= 7; /* Back up into prev month since r->week > 0. */
}
- if ((mday += 7 * r->week) >= monlen) {
+ mday += 7 * r->week;
+ if (mday >= monlen) {
mday -= 7;
}
/* So, 0-based day number is... */
@@ -805,21 +803,17 @@ time_t timegm(struct tm *timeptr)
#endif
/**********************************************************************/
-#if defined(L_strftime) || defined(L_strftime_l)
+#if defined(L_strftime) || defined(L_strftime_l) \
+ || defined(L_wcsftime) || defined(L_wcsftime_l)
#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
-libc_hidden_proto(strftime)
-
-libc_hidden_proto(strftime_l)
-
-size_t strftime(char *__restrict s, size_t maxsize,
- const char *__restrict format,
+size_t strftime(CHAR_T *__restrict s, size_t maxsize,
+ const CHAR_T *__restrict format,
const struct tm *__restrict timeptr)
{
return strftime_l(s, maxsize, format, timeptr, __UCLIBC_CURLOCALE);
}
-libc_hidden_def(strftime)
#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
@@ -1013,30 +1007,58 @@ static int load_field(int k, const struct tm *__restrict timeptr)
return r;
}
+#if defined __UCLIBC_HAS_WCHAR__ && (defined L_wcsftime || defined L_wcsftime_l)
+static wchar_t* fmt_to_wc_1(const char *src)
+{
+ mbstate_t mbstate;
+ size_t src_len = strlen(src);
+ wchar_t *dest = (wchar_t *)malloc((src_len + 1) * sizeof(wchar_t));
+ if (dest == NULL)
+ return NULL;
+ mbstate.__mask = 0;
+ if (mbsrtowcs(dest, &src, src_len + 1, &mbstate) == (size_t) -1) {
+ free(dest);
+ return NULL;
+ }
+ return dest;
+}
+# define fmt_to_wc(dest, src) \
+ dest = alloc[++allocno] = fmt_to_wc_1(src)
+# define to_wc(dest, src) \
+ dest = fmt_to_wc_1(src)
+#else
+# define fmt_to_wc(dest, src) (dest) = (src)
+# define to_wc(dest, src) (dest) = (src)
+#endif
+
#define MAX_PUSH 4
#ifdef __UCLIBC_MJN3_ONLY__
#warning TODO: Check multibyte format string validity.
#endif
-libc_hidden_proto(__XL_NPP(strftime))
-size_t __XL_NPP(strftime)(char *__restrict s, size_t maxsize,
- const char *__restrict format,
+size_t __XL_NPP(strftime)(CHAR_T *__restrict s, size_t maxsize,
+ const CHAR_T *__restrict format,
const struct tm *__restrict timeptr __LOCALE_PARAM )
{
long tzo;
- register const char *p;
- register const char *o;
+ register const CHAR_T *p;
+ const CHAR_T *o;
+ const char *ccp;
#ifndef __UCLIBC_HAS_TM_EXTENSIONS__
const rule_struct *rsp;
#endif
- const char *stack[MAX_PUSH];
+ const CHAR_T *stack[MAX_PUSH];
+#if defined __UCLIBC_HAS_WCHAR__ && (defined L_wcsftime || defined L_wcsftime_l)
+ const CHAR_T *alloc[MAX_PUSH];
+ int allocno = -1;
+#endif
size_t count;
size_t o_count;
- int field_val, i, j, lvl;
+ int field_val = 0, i = 0, j, lvl;
int x[3]; /* wday, yday, year */
int isofm, days;
- char buf[__UIM_BUFLEN_LONG];
+ char buf[__UIM_BUFLEN_LONG] = {0,};
unsigned char mod;
unsigned char code;
@@ -1061,8 +1083,26 @@ LOOP:
}
o_count = 1;
- if ((*(o = p) == '%') && (*++p != '%')) {
+ if ((*(o = (CHAR_T *)p) == '%') && (*++p != '%')) {
+#if 0 /* TODO, same for strptime */
+ /* POSIX.1-2008 allows %0xY %+nY %-nY etc. for certain formats.
+ * Just accept these for all (for now) */
+ const int plus = *p == '+';
+ CHAR_T *q = (CHAR_T *)p;
+ long int o_width = __XL_NPP(strtol)(p, &q, 0 __LOCALE_ARG);
+ if (o_width > 0 && o_width < 256) { /* arbitrary upper limit */
+ o_count = o_width;
+ if (plus) {
+ *s++ = '+';
+ --count;
+ }
+ p = q;
+ } else {
+ o_count = 2;
+ }
+#else
o_count = 2;
+#endif
mod = ILLEGAL_SPEC;
if ((*p == 'O') || (*p == 'E')) { /* modifier */
mod |= ((*p == 'O') ? NO_O_MOD : NO_E_MOD);
@@ -1086,31 +1126,33 @@ LOOP:
}
stack[lvl++] = ++p;
if ((code &= 0xf) < 8) {
- p = ((const char *) spec) + STACKED_STRINGS_START + code;
- p += *((unsigned char *)p);
+ ccp = (const char *)(spec + STACKED_STRINGS_START + code);
+ ccp += *ccp;
+ fmt_to_wc(p, ccp);
goto LOOP;
}
- p = ((const char *) spec) + STACKED_STRINGS_NL_ITEM_START
- + (code & 7);
+ ccp = (const char *)spec + STACKED_STRINGS_NL_ITEM_START + (code & 7);
+ fmt_to_wc(p, ccp);
#ifdef ENABLE_ERA_CODE
if ((mod & NO_E_MOD) /* Actually, this means E modifier present. */
- && (*(o = __XL_NPP(nl_langinfo)(_NL_ITEM(LC_TIME,
- (int)(((unsigned char *)p)[4]))
- __LOCALE_ARG
- )))
+ && (*(ccp = __XL_NPP(nl_langinfo)(_NL_ITEM(LC_TIME,
+ (int)(((unsigned char *)p)[4]))
+ __LOCALE_ARG
+ )))
) {
- p = o;
+ fmt_to_wc(p, ccp);
goto LOOP;
}
#endif
- p = __XL_NPP(nl_langinfo)(_NL_ITEM(LC_TIME,
- (int)(*((unsigned char *)p)))
- __LOCALE_ARG
- );
+ ccp = __XL_NPP(nl_langinfo)(_NL_ITEM(LC_TIME,
+ (int)(*((unsigned char *)p)))
+ __LOCALE_ARG
+ );
+ fmt_to_wc(p, ccp);
goto LOOP;
}
- o = ((const char *) spec) + 26; /* set to "????" */
+ ccp = (const char *)(spec + 26); /* set to "????" */
if ((code & MASK_SPEC) == CALC_SPEC) {
if (*p == 's') {
@@ -1125,15 +1167,16 @@ LOOP:
goto OUTPUT;
}
#ifdef TIME_T_IS_UNSIGNED
- o = _uintmaxtostr(buf + sizeof(buf) - 1,
+ ccp = _uintmaxtostr(buf + sizeof(buf) - 1,
(uintmax_t) t,
10, __UIM_DECIMAL);
#else
- o = _uintmaxtostr(buf + sizeof(buf) - 1,
+ ccp = _uintmaxtostr(buf + sizeof(buf) - 1,
(uintmax_t) t,
-10, __UIM_DECIMAL);
#endif
o_count = sizeof(buf);
+ fmt_to_wc(o, ccp);
goto OUTPUT;
} else if (((*p) | 0x20) == 'z') { /* 'z' or 'Z' */
@@ -1168,7 +1211,7 @@ LOOP:
#endif
if (*p == 'Z') {
- o = RSP_TZNAME;
+ ccp = RSP_TZNAME;
#ifdef __UCLIBC_HAS_TM_EXTENSIONS__
/* Sigh... blasted glibc extensions. Of course we can't
* count on the pointer being valid. Best we can do is
@@ -1179,17 +1222,18 @@ LOOP:
* case... although it always seems to use the embedded
* tm_gmtoff value. What we'll do instead is treat the
* timezone name as unknown/invalid and return "???". */
- if (!o) {
- o = "???";
+ if (!ccp) {
+ ccp = (const char *)(spec + 27); /* "???" */
}
#endif
- assert(o != NULL);
+ assert(ccp != NULL);
#if 0
- if (!o) { /* PARANOIA */
- o = spec+30; /* empty string */
+ if (!ccp) { /* PARANOIA */
+ ccp = spec+30; /* empty string */
}
#endif
o_count = SIZE_MAX;
+ fmt_to_wc(o, ccp);
#ifdef __UCLIBC_HAS_TM_EXTENSIONS__
goto OUTPUT;
#endif
@@ -1207,8 +1251,7 @@ LOOP:
i = 16 + 6; /* 0-fill, width = 4 */
}
-#ifdef __UCLIBC_HAS_TM_EXTENSIONS__
-#else
+#ifndef __UCLIBC_HAS_TM_EXTENSIONS__
__UCLIBC_MUTEX_UNLOCK(_time_tzlock);
if (*p == 'Z') {
goto OUTPUT;
@@ -1234,7 +1277,7 @@ LOOP:
--field_val;
}
} else { /* ((*p == 'g') || (*p == 'G') || (*p == 'V')) */
- ISO_LOOP:
+ISO_LOOP:
isofm = (((x[1] - x[0]) + 11) % 7) - 3; /* [-3,3] */
if (x[1] < isofm) { /* belongs to previous year */
@@ -1245,7 +1288,7 @@ LOOP:
field_val = ((x[1] - isofm) / 7) + 1; /* week # */
days = 365 + __isleap(x[2]);
- isofm = ((isofm + 7*53 + 3 - days)) %7 + days - 3; /* next year */
+ isofm = ((isofm + 7*53 + 3 - days)) % 7 + days - 3; /* next year */
if (x[1] >= isofm) { /* next year */
x[1] -= days;
++x[2];
@@ -1264,7 +1307,7 @@ LOOP:
}
} else {
i = TP_OFFSETS + (code & 0x1f);
- if ((field_val = load_field(spec[i],timeptr)) < 0) {
+ if ((field_val = load_field(spec[i], timeptr)) < 0) {
goto OUTPUT;
}
@@ -1276,7 +1319,7 @@ LOOP:
}
if (i & 32) {
field_val %= j;
- if (((i&128) + field_val) == 0) { /* mod 12? == 0 */
+ if (((i & 128) + field_val) == 0) { /* mod 12? == 0 */
field_val = j; /* set to 12 */
}
}
@@ -1289,17 +1332,25 @@ LOOP:
if ((code & MASK_SPEC) == STRING_SPEC) {
o_count = SIZE_MAX;
field_val += spec[STRINGS_NL_ITEM_START + (code & 0xf)];
- o = __XL_NPP(nl_langinfo)(_NL_ITEM(LC_TIME, field_val) __LOCALE_ARG );
+ ccp = __XL_NPP(nl_langinfo)(_NL_ITEM(LC_TIME, field_val) __LOCALE_ARG);
+ fmt_to_wc(o, ccp);
} else {
+#if 0 /* TODO, same for strptime */
+ size_t min_count = ((i >> 1) & 3) + 1;
+ if (o_count < min_count)
+ o_count = min_count;
+#else
o_count = ((i >> 1) & 3) + 1;
- o = buf + o_count;
+#endif
+ ccp = buf + o_count;
do {
- *(char *)(--o) = '0' + (field_val % 10);
+ *(char *)(--ccp) = '0' + (field_val % 10);
field_val /= 10;
- } while (o > buf);
+ } while (ccp > buf);
if (*buf == '0') {
*buf = ' ' + (i & 16);
}
+ fmt_to_wc(o, ccp);
}
}
@@ -1310,9 +1361,15 @@ OUTPUT:
--o_count;
--count;
}
+#if defined __UCLIBC_HAS_WCHAR__ && (defined L_wcsftime || defined L_wcsftime_l)
+ if (allocno >= 0)
+ free((void *)alloc[allocno--]);
+#endif
goto LOOP;
}
-libc_hidden_def(__XL_NPP(strftime))
+# ifdef L_strftime_l
+libc_hidden_def(strftime_l)
+# endif
#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
@@ -1330,16 +1387,11 @@ libc_hidden_def(__XL_NPP(strftime))
#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
-libc_hidden_proto(strptime)
-
-libc_hidden_proto(strptime_l)
-
char *strptime(const char *__restrict buf, const char *__restrict format,
struct tm *__restrict tm)
{
return strptime_l(buf, format, tm, __UCLIBC_CURLOCALE);
}
-libc_hidden_def(strptime)
#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
@@ -1485,7 +1537,6 @@ static const unsigned char spec[] = {
#define MAX_PUSH 4
-libc_hidden_proto(__XL_NPP(strptime))
char *__XL_NPP(strptime)(const char *__restrict buf, const char *__restrict format,
struct tm *__restrict tm __LOCALE_PARAM)
{
@@ -1555,17 +1606,18 @@ LOOP:
#ifdef ENABLE_ERA_CODE
if ((mod & NO_E_MOD) /* Actually, this means E modifier present. */
&& (*(o = __XL_NPP(nl_langinfo)(_NL_ITEM(LC_TIME,
- (int)(((unsigned char *)p)[4]))
- __LOCALE_ARG
- )))
+ (int)(((unsigned char *)p)[4]))
+ __LOCALE_ARG
+ )))
) {
p = o;
goto LOOP;
}
#endif
p = __XL_NPP(nl_langinfo)(_NL_ITEM(LC_TIME,
- (int)(*((unsigned char *)p)))
- __LOCALE_ARG );
+ (int)(*((unsigned char *)p)))
+ __LOCALE_ARG
+ );
goto LOOP;
}
@@ -1579,7 +1631,7 @@ LOOP:
do {
--j;
o = __XL_NPP(nl_langinfo)(i+j __LOCALE_ARG);
- if (!__XL_NPP(strncasecmp)(buf,o,strlen(o) __LOCALE_ARG) && *o) {
+ if (!__XL_NPP(strncasecmp)(buf, o, strlen(o) __LOCALE_ARG) && *o) {
do { /* Found a match. */
++buf;
} while (*++o);
@@ -1669,7 +1721,7 @@ LOOP:
fields[(*x) >> 3] = i;
- if (((unsigned char)(*x - (10<< 3) + 0 + 0)) <= 8) { /* %C or %y */
+ if (((unsigned char)(*x - (10 << 3) + 0 + 0)) <= 8) { /* %C or %y */
if ((j = fields[10]) < 0) { /* No %C, so i must be %y data. */
if (i <= 68) { /* Map [0-68] to 2000+i */
i += 100;
@@ -1695,7 +1747,9 @@ LOOP:
}
return NULL;
}
-libc_hidden_def(__XL_NPP(strptime))
+# ifdef L_strptime_l
+libc_hidden_def(strptime_l)
+# endif
#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
@@ -1825,53 +1879,100 @@ static const char *getnumber(register const char *e, int *pn)
#ifndef __UCLIBC_HAS_TZ_FILE_READ_MANY__
static smallint TZ_file_read; /* Let BSS initialization set this to 0. */
-#endif /* __UCLIBC_HAS_TZ_FILE_READ_MANY__ */
+#endif
static char *read_TZ_file(char *buf)
{
+ int r;
int fd;
- ssize_t r;
- size_t todo;
char *p = NULL;
- if ((fd = open(__UCLIBC_TZ_FILE_PATH__, O_RDONLY)) >= 0) {
- todo = TZ_BUFLEN;
+ fd = open(__UCLIBC_TZ_FILE_PATH__, O_RDONLY);
+ if (fd >= 0) {
+#if 0
+ /* TZ are small *files*. On files, short reads
+ * only occur on EOF (unlike, say, pipes).
+ * The code below is pedanticallly more correct,
+ * but this way we always read at least twice:
+ * 1st read is short, 2nd one is zero bytes.
+ */
+ size_t todo = TZ_BUFLEN;
p = buf;
do {
- if ((r = read(fd, p, todo)) < 0) {
+ r = read(fd, p, todo);
+ if (r < 0)
goto ERROR;
- }
- if (r == 0) {
+ if (r == 0)
break;
- }
p += r;
todo -= r;
} while (todo);
-
- if ((p > buf) && (p[-1] == '\n')) { /* Must end with newline. */
+#else
+ /* Shorter, and does one fewer read syscall */
+ r = read(fd, buf, TZ_BUFLEN);
+ if (r < 0)
+ goto ERROR;
+ p = buf + r;
+#endif
+ if ((p > buf) && (p[-1] == '\n')) { /* Must end with newline */
p[-1] = 0;
p = buf;
#ifndef __UCLIBC_HAS_TZ_FILE_READ_MANY__
TZ_file_read = 1;
-#endif /* __UCLIBC_HAS_TZ_FILE_READ_MANY__ */
+#endif
} else {
ERROR:
p = NULL;
}
close(fd);
}
+#ifdef __UCLIBC_FALLBACK_TO_ETC_LOCALTIME__
+ else {
+ fd = open("/etc/localtime", O_RDONLY);
+ if (fd >= 0) {
+ r = read(fd, buf, TZ_BUFLEN);
+ if (r != TZ_BUFLEN
+ || strncmp(buf, "TZif", 4) != 0
+ || (unsigned char)buf[4] < 2
+ || lseek(fd, -TZ_BUFLEN, SEEK_END) < 0
+ ) {
+ goto ERROR;
+ }
+ /* tzfile.h from tzcode database says about TZif2+ files:
+ **
+ ** If tzh_version is '2' or greater, the above is followed by a second instance
+ ** of tzhead and a second instance of the data in which each coded transition
+ ** time uses 8 rather than 4 chars,
+ ** then a POSIX-TZ-environment-variable-style string for use in handling
+ ** instants after the last transition time stored in the file
+ ** (with nothing between the newlines if there is no POSIX representation for
+ ** such instants).
+ */
+ r = read(fd, buf, TZ_BUFLEN);
+ if (r <= 0 || buf[--r] != '\n')
+ goto ERROR;
+ buf[r] = 0;
+ while (r != 0) {
+ if (buf[--r] == '\n') {
+ p = buf + r + 1;
+#ifndef __UCLIBC_HAS_TZ_FILE_READ_MANY__
+ TZ_file_read = 1;
+#endif
+ break;
+ }
+ } /* else ('\n' not found): p remains NULL */
+ close(fd);
+ }
+ }
+#endif /* __UCLIBC_FALLBACK_TO_ETC_LOCALTIME__ */
return p;
}
#endif /* __UCLIBC_HAS_TZ_FILE__ */
-#ifndef __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(isascii)
-#endif
-
void tzset(void)
{
- _time_tzset((time(NULL)) < new_rule_starts);
+ _time_tzset((time(NULL)) < new_rule_starts);
}
void _time_tzset(int use_old_rules)
@@ -1885,43 +1986,41 @@ void _time_tzset(int use_old_rules)
char c;
#ifdef __UCLIBC_HAS_TZ_FILE__
char buf[TZ_BUFLEN];
-#endif /* __UCLIBC_HAS_TZ_FILE__ */
+#endif
#ifdef __UCLIBC_HAS_TZ_CACHING__
static char oldval[TZ_BUFLEN]; /* BSS-zero'd. */
-#endif /* __UCLIBC_HAS_TZ_CACHING__ */
+#endif
+ /* Put this inside the lock to prevent the possibility of two different
+ * timezones being used in a threaded app. */
__UCLIBC_MUTEX_LOCK(_time_tzlock);
e = getenv(TZ); /* TZ env var always takes precedence. */
#if defined(__UCLIBC_HAS_TZ_FILE__) && !defined(__UCLIBC_HAS_TZ_FILE_READ_MANY__)
- /* Put this inside the lock to prevent the possiblity of two different
- * timezones being used in a threaded app. */
-
- if (e != NULL) {
- TZ_file_read = 0; /* Reset if the TZ env var is set. */
- } else if (TZ_file_read) {
+ if (e) {
+ /* Never use TZfile if TZ env var is set. */
+ TZ_file_read = 0;
+ }
+ if (TZ_file_read) {
+ /* We already parsed TZfile before, skip everything. */
goto FAST_DONE;
}
-#endif /* defined(__UCLIBC_HAS_TZ_FILE__) && !defined(__UCLIBC_HAS_TZ_FILE_READ_MANY__) */
+#endif
/* Warning!!! Since uClibc doesn't do lib locking, the following is
* potentially unsafe in a multi-threaded program since it is remotely
* possible that another thread could call setenv() for TZ and overwrite
* the string being parsed. So, don't do that... */
- if ((!e /* TZ env var not set... */
#ifdef __UCLIBC_HAS_TZ_FILE__
- && !(e = read_TZ_file(buf)) /* and no file or invalid file */
-#endif /* __UCLIBC_HAS_TZ_FILE__ */
- ) || !*e) { /* or set to empty string. */
-ILLEGAL: /* TODO: Clean up the following... */
-#ifdef __UCLIBC_HAS_TZ_CACHING__
- *oldval = 0; /* Set oldval to an empty string. */
-#endif /* __UCLIBC_HAS_TZ_CACHING__ */
- memset(_time_tzinfo, 0, 2*sizeof(rule_struct));
- strcpy(_time_tzinfo[0].tzname, UTC);
- goto DONE;
+ if (!e)
+ e = read_TZ_file(buf);
+#endif
+ if (!e /* TZ env var not set and no TZfile (or bad TZfile) */
+ || !*e /* or set to empty string. */
+ ) {
+ goto ILLEGAL;
}
if (*e == ':') { /* Ignore leading ':'. */
@@ -1929,14 +2028,15 @@ ILLEGAL: /* TODO: Clean up the following... */
}
#ifdef __UCLIBC_HAS_TZ_CACHING__
- if (strcmp(e, oldval) == 0) { /* Same string as last time... */
- goto FAST_DONE; /* So nothing to do. */
+ if (strcmp(e, oldval) == 0) {
+ /* Same string as last time... nothing to do. */
+ goto FAST_DONE;
}
/* Make a copy of the TZ env string. It won't be nul-terminated if
* it is too long, but it that case it will be illegal and will be reset
* to the empty string anyway. */
strncpy(oldval, e, TZ_BUFLEN);
-#endif /* __UCLIBC_HAS_TZ_CACHING__ */
+#endif
count = 0;
new_rules[1].tzname[0] = 0;
@@ -1951,10 +2051,11 @@ LOOP:
s = new_rules[count].tzname;
n = 0;
while (*e
- && isascii(*e) /* SUSv3 requires char in portable char set. */
- && (isalpha(*e)
- || (c && (isalnum(*e) || (*e == '+') || (*e == '-'))))
- ) {
+ && isascii(*e) /* SUSv3 requires char in portable char set. */
+ && (isalpha(*e)
+ || (c && (isalnum(*e) || (*e == '+') || (*e == '-')))
+ )
+ ) {
*s++ = *e++;
if (++n > TZNAME_MAX) {
goto ILLEGAL;
@@ -1963,8 +2064,8 @@ LOOP:
*s = 0;
if ((n < 3) /* Check for minimum length. */
- || (c && (*e++ != c)) /* Match any quoting '<'. */
- ) {
+ || (c && (*e++ != c)) /* Match any quoting '<'. */
+ ) {
goto ILLEGAL;
}
@@ -1979,7 +2080,8 @@ LOOP:
}
++e;
- if (!(e = getoffset(e, &off))) {
+ e = getoffset(e, &off);
+ if (!e) {
goto ILLEGAL;
}
@@ -1998,15 +2100,15 @@ SKIP_OFFSET:
} else { /* OK, we have dst, so get some rules. */
count = 0;
if (!*e) { /* No rules so default to US rules. */
- e = use_old_rules ? DEFAULT_RULES : DEFAULT_2007_RULES;
+ e = use_old_rules ? DEFAULT_RULES : DEFAULT_2007_RULES;
#ifdef DEBUG_TZSET
if (e == DEFAULT_RULES)
- printf("tzset: Using old rules.\n");
+ printf("tzset: Using old rules.\n");
else if (e == DEFAULT_2007_RULES)
- printf("tzset: Using new rules\n");
+ printf("tzset: Using new rules\n");
else
- printf("tzset: Using undefined rules\n");
-#endif /* DEBUG_TZSET */
+ printf("tzset: Using undefined rules\n");
+#endif
}
do {
@@ -2016,7 +2118,8 @@ SKIP_OFFSET:
n = 365;
s = (char *) RULE;
- if ((c = *e++) == 'M') {
+ c = *e++;
+ if (c == 'M') {
n = 12;
} else if (c == 'J') {
s += 8;
@@ -2026,26 +2129,31 @@ SKIP_OFFSET:
s += 6;
}
- *(p = &new_rules[count].rule_type) = c;
+ p = &new_rules[count].rule_type;
+ *p = c;
if (c != 'M') {
p -= 2;
}
do {
++s;
- if (!(e = getnumber(e, &f))
- || (((unsigned int)(f - s[1])) > n)
- || (*s && (*e++ != *s))
- ) {
+ e = getnumber(e, &f);
+ if (!e
+ || ((unsigned int)(f - s[1]) > n)
+ || (*s && (*e++ != *s))
+ ) {
goto ILLEGAL;
}
*--p = f;
- } while ((n = *(s += 2)) > 0);
+ s += 2;
+ n = *s;
+ } while (n > 0);
off = 2 * 60 * 60; /* Default to 2:00:00 */
if (*e == '/') {
++e;
- if (!(e = getoffset(e, &off))) {
+ e = getoffset(e, &off);
+ if (!e) {
goto ILLEGAL;
}
}
@@ -2053,7 +2161,13 @@ SKIP_OFFSET:
} while (++count < 2);
if (*e) {
- goto ILLEGAL;
+ILLEGAL:
+#ifdef __UCLIBC_HAS_TZ_CACHING__
+ oldval[0] = 0; /* oldval = "" */
+#endif
+ memset(_time_tzinfo, 0, sizeof(_time_tzinfo));
+ strcpy(_time_tzinfo[0].tzname, UTC);
+ goto DONE;
}
}
@@ -2064,7 +2178,8 @@ DONE:
daylight = !!_time_tzinfo[1].tzname[0];
timezone = _time_tzinfo[0].gmt_offset;
-#if defined(__UCLIBC_HAS_TZ_FILE__) || defined(__UCLIBC_HAS_TZ_CACHING__)
+#if (defined(__UCLIBC_HAS_TZ_FILE__) && !defined(__UCLIBC_HAS_TZ_FILE_READ_MANY__)) || \
+ defined(__UCLIBC_HAS_TZ_CACHING__)
FAST_DONE:
#endif
__UCLIBC_MUTEX_UNLOCK(_time_tzlock);
@@ -2210,7 +2325,6 @@ struct tm attribute_hidden *_time_t2tm(const time_t *__restrict timer,
t = 365;
}
-
*p += ((int) t); /* result[7] .. tm_yday */
p -= 2; /* at result[5] */
@@ -2386,7 +2500,7 @@ DST_CORRECT:
__time_localtime_tzi(&t, (struct tm *)p, tzi);
if (t == ((time_t)(-1))) { /* Remember, time_t can be unsigned. */
- goto DONE;
+ goto DONE;
}
if ((d < 0) && (((struct tm *)p)->tm_isdst != default_dst)) {
@@ -2410,35 +2524,9 @@ DONE:
#endif
/**********************************************************************/
-#if defined(L_wcsftime) || defined(L_wcsftime_l)
+#if (defined(L_wcsftime) || defined(L_wcsftime_l))
-#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
-
-libc_hidden_proto(wcsftime)
-
-libc_hidden_proto(wcsftime_l)
-
-size_t wcsftime(wchar_t *__restrict s, size_t maxsize,
- const wchar_t *__restrict format,
- const struct tm *__restrict timeptr)
-{
- return wcsftime_l(s, maxsize, format, timeptr, __UCLIBC_CURLOCALE);
-}
-libc_hidden_def(wcsftime)
-
-#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
-
-libc_hidden_proto(__XL_NPP(wcsftime))
-size_t __XL_NPP(wcsftime)(wchar_t *__restrict s, size_t maxsize,
- const wchar_t *__restrict format,
- const struct tm *__restrict timeptr __LOCALE_PARAM )
-{
-#warning wcsftime always fails
- return 0; /* always fail */
-}
-libc_hidden_def(__XL_NPP(wcsftime))
-
-#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+/* Implemented via strftime / strftime_l wchar_t variants */
#endif
/**********************************************************************/
diff --git a/libc/misc/ttyent/Makefile.in b/libc/misc/ttyent/Makefile.in
index 288a4c09b..02d7df8d1 100644
--- a/libc/misc/ttyent/Makefile.in
+++ b/libc/misc/ttyent/Makefile.in
@@ -1,21 +1,23 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := getttyent.c
+subdirs += libc/misc/ttyent
+
+CSRC-y := getttyent.c
MISC_TTYENT_DIR := $(top_srcdir)libc/misc/ttyent
MISC_TTYENT_OUT := $(top_builddir)libc/misc/ttyent
-MISC_TTYENT_SRC := $(patsubst %.c,$(MISC_TTYENT_DIR)/%.c,$(CSRC))
-MISC_TTYENT_OBJ := $(patsubst %.c,$(MISC_TTYENT_OUT)/%.o,$(CSRC))
+MISC_TTYENT_SRC := $(patsubst %.c,$(MISC_TTYENT_DIR)/%.c,$(CSRC-y))
+MISC_TTYENT_OBJ := $(patsubst %.c,$(MISC_TTYENT_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_TTYENT_OBJ)
-objclean-y += misc_ttyent_objclean
+objclean-y += CLEAN_libc/misc/ttyent
-misc_ttyent_objclean:
- $(RM) $(MISC_TTYENT_OUT)/*.{o,os}
+CLEAN_libc/misc/ttyent:
+ $(do_rm) $(addprefix $(MISC_TTYENT_OUT)/*., o os)
diff --git a/libc/misc/ttyent/getttyent.c b/libc/misc/ttyent/getttyent.c
index b55cdb267..0441cb6a1 100644
--- a/libc/misc/ttyent/getttyent.c
+++ b/libc/misc/ttyent/getttyent.c
@@ -30,29 +30,11 @@
#include <features.h>
#include <ttyent.h>
#include <stdio.h>
-#include <stdio_ext.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#ifdef __UCLIBC_HAS_THREADS__
-#include <pthread.h>
-#endif
-
-/* Experimentally off - libc_hidden_proto(strchr) */
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strncmp) */
-libc_hidden_proto(__fsetlocking)
-libc_hidden_proto(rewind)
-libc_hidden_proto(fgets_unlocked)
-libc_hidden_proto(getc_unlocked)
-libc_hidden_proto(__fgetc_unlocked)
-libc_hidden_proto(fopen)
-libc_hidden_proto(fclose)
-libc_hidden_proto(abort)
-#ifdef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_b_loc)
-#elif defined __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__ctype_b)
+# include <stdio_ext.h>
#endif
static char zapchar;
@@ -102,7 +84,6 @@ static char * value(register char *p)
return ((p = strchr(p, '=')) ? ++p : NULL);
}
-libc_hidden_proto(setttyent)
int setttyent(void)
{
@@ -120,7 +101,6 @@ int setttyent(void)
}
libc_hidden_def(setttyent)
-libc_hidden_proto(getttyent)
struct ttyent * getttyent(void)
{
register int c;
@@ -201,7 +181,6 @@ struct ttyent * getttyent(void)
}
libc_hidden_def(getttyent)
-libc_hidden_proto(endttyent)
int endttyent(void)
{
int rval;
diff --git a/libc/misc/utmp/Makefile.in b/libc/misc/utmp/Makefile.in
index ff175dc64..6c54ade96 100644
--- a/libc/misc/utmp/Makefile.in
+++ b/libc/misc/utmp/Makefile.in
@@ -1,21 +1,24 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := utent.c wtent.c
+subdirs += libc/misc/utmp
+
+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
-MISC_UTMP_SRC := $(patsubst %.c,$(MISC_UTMP_DIR)/%.c,$(CSRC))
-MISC_UTMP_OBJ := $(patsubst %.c,$(MISC_UTMP_OUT)/%.o,$(CSRC))
+MISC_UTMP_SRC := $(patsubst %.c,$(MISC_UTMP_DIR)/%.c,$(CSRC-y))
+MISC_UTMP_OBJ := $(patsubst %.c,$(MISC_UTMP_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_UTMP_OBJ)
-objclean-y += misc_utmp_objclean
+objclean-y += CLEAN_libc/misc/utmp
-misc_utmp_objclean:
- $(RM) $(MISC_UTMP_OUT)/*.{o,os}
+CLEAN_libc/misc/utmp:
+ $(do_rm) $(addprefix $(MISC_UTMP_OUT)/*., o os)
diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c
index 6c1793e65..16f4b115f 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
@@ -17,194 +18,216 @@
#include <fcntl.h>
#include <paths.h>
#include <errno.h>
+#include <malloc.h>
#include <string.h>
-#include <utmp.h>
-
-/* Experimentally off - libc_hidden_proto(strcmp) */
-/* Experimentally off - libc_hidden_proto(strdup) */
-/* Experimentally off - libc_hidden_proto(strncmp) */
-libc_hidden_proto(read)
-libc_hidden_proto(write)
-libc_hidden_proto(open)
-libc_hidden_proto(fcntl)
-libc_hidden_proto(close)
-libc_hidden_proto(lseek)
-
+#include "internal/utmp.h"
+#include <not-cancel.h>
#include <bits/uClibc_mutex.h>
-__UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER);
-
+__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 = (const char *) default_file_name;
+static struct UT *static_utmp = NULL;
+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(void)
+static void __set_unlocked(void)
{
- int ret;
-
- if (static_fd == -1) {
- if ((static_fd = open(static_ut_name, O_RDWR)) < 0) {
- if ((static_fd = open(static_ut_name, O_RDONLY)) < 0) {
- goto bummer;
- }
- }
- /* Make sure the file will be closed on exec() */
- ret = fcntl(static_fd, F_GETFD, 0);
- if (ret >= 0) {
- ret = fcntl(static_fd, F_SETFD, ret | FD_CLOEXEC);
- }
- if (ret < 0) {
-bummer:
- static_fd = -1;
- close(static_fd);
- return;
+ if (static_fd < 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);
+#endif
+ return;
}
- }
- lseek(static_fd, 0, SEEK_SET);
- return;
+ lseek(static_fd, 0, SEEK_SET);
}
-
-libc_hidden_proto(setutent)
-void setutent(void)
+#if defined __UCLIBC_HAS_THREADS__
+void set(void)
{
- __UCLIBC_MUTEX_LOCK(utmplock);
- __setutent();
- __UCLIBC_MUTEX_UNLOCK(utmplock);
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ __set_unlocked();
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
}
-libc_hidden_def(setutent)
+#else
+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(int utmp_fd)
+static struct UT *__get_unlocked(void)
{
- struct utmp *ret = NULL;
+ if (static_fd < 0) {
+ __set_unlocked();
+ if (static_fd < 0)
+ return NULL;
+ }
- if (utmp_fd == -1) {
- __setutent();
- }
- if (utmp_fd == -1) {
- return NULL;
- }
+ if (static_utmp == NULL)
+ static_utmp = (struct UT *)__uc_malloc(sizeof(struct UT));
- if (read(utmp_fd, (char *) &static_utmp, sizeof(struct utmp)) == sizeof(struct utmp))
- {
- ret = &static_utmp;
- }
+ if (read_not_cancel(static_fd, static_utmp,
+ sizeof(struct UT)) == sizeof(struct UT)) {
+ return static_utmp;
+ }
- return ret;
+ return NULL;
}
-
-void endutent(void)
+#if defined __UCLIBC_HAS_THREADS__
+struct UT *get(void)
{
- __UCLIBC_MUTEX_LOCK(utmplock);
- if (static_fd != -1)
- close(static_fd);
- static_fd = -1;
- __UCLIBC_MUTEX_UNLOCK(utmplock);
+ struct UT *ret;
+
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ ret = __get_unlocked();
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return ret;
}
+#else
+strong_alias(__get_unlocked,get)
+#endif
+/* not used in libc_hidden_def(get) */
+other(getutxent,getutent)
-struct utmp *getutent(void)
+void end(void)
{
- struct utmp *ret = NULL;
-
- __UCLIBC_MUTEX_LOCK(utmplock);
- ret = __getutent(static_fd);
- __UCLIBC_MUTEX_UNLOCK(utmplock);
- return ret;
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ if (static_fd >= 0)
+ close_not_cancel_no_status(static_fd);
+ static_fd = -1;
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
}
+/* not used in libc_hidden_def(end) */
+other(endutxent,endutent)
/* This function must be called with the LOCK held */
-static struct utmp *__getutid(const struct utmp *utmp_entry)
+static struct UT *__getid_unlocked(const struct UT *utmp_entry)
{
- struct utmp *lutmp;
-
- while ((lutmp = __getutent(static_fd)) != NULL) {
- if ( (utmp_entry->ut_type == RUN_LVL ||
- utmp_entry->ut_type == BOOT_TIME ||
- utmp_entry->ut_type == NEW_TIME ||
- utmp_entry->ut_type == OLD_TIME) &&
- lutmp->ut_type == utmp_entry->ut_type)
- {
- return lutmp;
- }
- if ( (utmp_entry->ut_type == INIT_PROCESS ||
- utmp_entry->ut_type == DEAD_PROCESS ||
- utmp_entry->ut_type == LOGIN_PROCESS ||
- utmp_entry->ut_type == USER_PROCESS) &&
- !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id)))
- {
- 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;
+ }
+ }
- return NULL;
+ return NULL;
}
-
-libc_hidden_proto(getutid)
-struct utmp *getutid(const struct utmp *utmp_entry)
+#if defined __UCLIBC_HAS_THREADS__
+struct UT *getid(const struct UT *utmp_entry)
{
- struct utmp *ret = NULL;
+ struct UT *ret;
- __UCLIBC_MUTEX_LOCK(utmplock);
- ret = __getutid(utmp_entry);
- __UCLIBC_MUTEX_UNLOCK(utmplock);
- return ret;
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ ret = __getid_unlocked(utmp_entry);
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return ret;
}
-libc_hidden_def(getutid)
+#else
+strong_alias(__getid_unlocked,getid)
+#endif
+/* not used in libc_hidden_def(getid) */
+other(getutxid,getutid)
-struct utmp *getutline(const struct utmp *utmp_entry)
+struct UT *getline(const struct UT *utmp_entry)
{
- struct utmp *lutmp = NULL;
-
- __UCLIBC_MUTEX_LOCK(utmplock);
- while ((lutmp = __getutent(static_fd)) != NULL) {
- if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) &&
- !strcmp(lutmp->ut_line, utmp_entry->ut_line)) {
- 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;
}
+/* libc_hidden_def(getline) */
+other(getutxline,getutline)
-struct utmp *pututline (const struct utmp *utmp_entry)
+struct UT *putline(const struct UT *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 utmp), SEEK_CUR);
-
- if (__getutid(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;
+ __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;
}
+/* not used in libc_hidden_def(putline) */
+other(pututxline,pututline)
-int utmpname (const char *new_ut_name)
+int name(const char *new_file)
{
- __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;
+ __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;
+ }
}
- }
- if (static_fd != -1)
- close(static_fd);
- static_fd = -1;
- __UCLIBC_MUTEX_UNLOCK(utmplock);
- return 0;
+ 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)? */
+}
+/* not used in libc_hidden_def(name) */
+other(utmpxname,utmpname)
+
+void updw(const char *wtmp_file, const struct UT *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 UT));
+ lockf(fd, F_ULOCK, 0);
+ close_not_cancel_no_status(fd);
+ }
+ }
}
+/* not used in libc_hidden_def(updw) */
+other(updwtmpx,updwtmp)
diff --git a/libc/misc/utmp/wtent.c b/libc/misc/utmp/wtent.c
deleted file mode 100644
index 9430bbb19..000000000
--- a/libc/misc/utmp/wtent.c
+++ /dev/null
@@ -1,58 +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>
-#include <fcntl.h>
-#include <sys/file.h>
-
-#if 0
-/* Experimentally off - libc_hidden_proto(memset) */
-/* Experimentally off - libc_hidden_proto(strncpy) */
-libc_hidden_proto(updwtmp)
-#endif
-libc_hidden_proto(open)
-libc_hidden_proto(write)
-libc_hidden_proto(close)
-libc_hidden_proto(lockf)
-libc_hidden_proto(gettimeofday)
-
-#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 (struct utmp));
-
- 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
-
-void updwtmp(const char *wtmp_file, const struct utmp *lutmp)
-{
- int fd;
-
- fd = open(wtmp_file, O_APPEND | O_WRONLY, 0);
- if (fd >= 0) {
- if (lockf(fd, F_LOCK, 0)==0) {
- write(fd, (const char *) lutmp, sizeof(struct utmp));
- lockf(fd, F_ULOCK, 0);
- close(fd);
- }
- }
-}
diff --git a/libc/misc/wchar/Makefile.in b/libc/misc/wchar/Makefile.in
index db01f97cc..32a8dbc62 100644
--- a/libc/misc/wchar/Makefile.in
+++ b/libc/misc/wchar/Makefile.in
@@ -1,6 +1,6 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
@@ -16,24 +16,24 @@
# wcsftime
#
+subdirs += libc/misc/wchar
+
# multi source wchar.c
-CSRC := btowc.c wctob.c mbsinit.c mbrlen.c mbrtowc.c wcrtomb.c mbsrtowcs.c \
+CSRC-y := btowc.c wctob.c mbsinit.c mbrlen.c mbrtowc.c wcrtomb.c mbsrtowcs.c \
wcsrtombs.c _wchar_utf8sntowcs.c _wchar_wcsntoutf8s.c \
mbsnrtowcs.c wcsnrtombs.c wcwidth.c wcswidth.c
-ifeq ($(UCLIBC_HAS_LOCALE),y)
-CSRC += iconv.c
-endif
+CSRC-$(UCLIBC_HAS_LOCALE) += iconv.c
MISC_WCHAR_DIR := $(top_srcdir)libc/misc/wchar
MISC_WCHAR_OUT := $(top_builddir)libc/misc/wchar
-MISC_WCHAR_SRC := $(patsubst %.c,$(MISC_WCHAR_DIR)/%.c,$(CSRC))
-MISC_WCHAR_OBJ := $(patsubst %.c,$(MISC_WCHAR_OUT)/%.o,$(CSRC))
+MISC_WCHAR_SRC := $(patsubst %.c,$(MISC_WCHAR_DIR)/%.c,$(CSRC-y))
+MISC_WCHAR_OBJ := $(patsubst %.c,$(MISC_WCHAR_OUT)/%.o,$(CSRC-y))
libc-$(UCLIBC_HAS_WCHAR) += $(MISC_WCHAR_OBJ)
-objclean-y += misc_wchar_objclean
+objclean-y += CLEAN_libc/misc/wchar
-misc_wchar_objclean:
- $(RM) $(MISC_WCHAR_OUT)/*.{o,os}
+CLEAN_libc/misc/wchar:
+ $(do_rm) $(addprefix $(MISC_WCHAR_OUT)/*., o os)
diff --git a/libc/misc/wchar/wchar.c b/libc/misc/wchar/wchar.c
index 567be8585..966f78d19 100644
--- a/libc/misc/wchar/wchar.c
+++ b/libc/misc/wchar/wchar.c
@@ -12,8 +12,8 @@
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
*/
/* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
@@ -97,7 +97,7 @@
*
* Manuel
*/
-
+#ifdef _LIBC
#include <errno.h>
#include <stddef.h>
#include <limits.h>
@@ -119,7 +119,7 @@
#endif
#endif /* __UCLIBC_MJN3_ONLY__ */
-#define ENCODING ((__UCLIBC_CURLOCALE_DATA).encoding)
+#define ENCODING (__UCLIBC_CURLOCALE->encoding)
#define Cc2wc_IDX_SHIFT __LOCALE_DATA_Cc2wc_IDX_SHIFT
#define Cc2wc_ROW_LEN __LOCALE_DATA_Cc2wc_ROW_LEN
@@ -170,13 +170,11 @@ extern size_t _wchar_utf8sntowcs(wchar_t *__restrict pwc, size_t wn,
extern size_t _wchar_wcsntoutf8s(char *__restrict s, size_t n,
const wchar_t **__restrict src, size_t wn) attribute_hidden;
-
+#endif
/**********************************************************************/
#ifdef L_btowc
-libc_hidden_proto(mbrtowc)
-libc_hidden_proto(btowc)
wint_t btowc(int c)
{
#ifdef __CTYPE_HAS_8_BIT_LOCALES
@@ -188,24 +186,24 @@ wint_t btowc(int c)
if (c != EOF) {
*buf = (unsigned char) c;
mbstate.__mask = 0; /* Initialize the mbstate. */
- if (mbrtowc(&wc, buf, 1, &mbstate) <= 1) {
+ if (mbrtowc(&wc, (char*) buf, 1, &mbstate) <= 1) {
return wc;
}
}
return WEOF;
-#else /* __CTYPE_HAS_8_BIT_LOCALES */
+#else /* !__CTYPE_HAS_8_BIT_LOCALES */
#ifdef __UCLIBC_HAS_LOCALE__
assert((ENCODING == __ctype_encoding_7_bit)
|| (ENCODING == __ctype_encoding_utf8));
-#endif /* __UCLIBC_HAS_LOCALE__ */
+#endif
/* If we don't have 8-bit locale support, then this is trivial since
* anything outside of 0-0x7f is illegal in C/POSIX and UTF-8 locales. */
return (((unsigned int)c) < 0x80) ? c : WEOF;
-#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+#endif /* !__CTYPE_HAS_8_BIT_LOCALES */
}
libc_hidden_def(btowc)
@@ -215,7 +213,6 @@ libc_hidden_def(btowc)
/* Note: We completely ignore ps in all currently supported conversions. */
-libc_hidden_proto(wcrtomb)
int wctob(wint_t c)
{
@@ -223,7 +220,7 @@ int wctob(wint_t c)
unsigned char buf[MB_LEN_MAX];
- return (wcrtomb(buf, c, NULL) == 1) ? *buf : EOF;
+ return (wcrtomb((char*) buf, c, NULL) == 1) ? *buf : EOF;
#else /* __CTYPE_HAS_8_BIT_LOCALES */
@@ -246,7 +243,6 @@ int wctob(wint_t c)
/**********************************************************************/
#ifdef L_mbsinit
-libc_hidden_proto(mbsinit)
int mbsinit(const mbstate_t *ps)
{
return !ps || !ps->__mask;
@@ -257,9 +253,7 @@ libc_hidden_def(mbsinit)
/**********************************************************************/
#ifdef L_mbrlen
-libc_hidden_proto(mbrtowc)
-libc_hidden_proto(mbrlen)
size_t mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps)
{
static mbstate_t mbstate; /* Rely on bss 0-init. */
@@ -272,9 +266,7 @@ libc_hidden_def(mbrlen)
/**********************************************************************/
#ifdef L_mbrtowc
-libc_hidden_proto(mbsnrtowcs)
-libc_hidden_proto(mbrtowc)
size_t mbrtowc(wchar_t *__restrict pwc, const char *__restrict s,
size_t n, mbstate_t *__restrict ps)
{
@@ -294,7 +286,9 @@ size_t mbrtowc(wchar_t *__restrict pwc, const char *__restrict s,
s = empty_string;
n = 1;
} else if (*s == '\0') {
- /* According to the ISO C 89 standard this is the expected behaviour. */
+ if (pwc)
+ *pwc = '\0';
+ /* According to the ISO C 89 standard this is the expected behaviour. */
return 0;
} else if (!n) {
/* TODO: change error code? */
@@ -338,12 +332,10 @@ libc_hidden_def(mbrtowc)
/**********************************************************************/
#ifdef L_wcrtomb
-libc_hidden_proto(wcsnrtombs)
/* Note: We completely ignore ps in all currently supported conversions. */
/* TODO: Check for valid state anyway? */
-libc_hidden_proto(wcrtomb)
size_t wcrtomb(register char *__restrict s, wchar_t wc,
mbstate_t *__restrict ps)
{
@@ -372,9 +364,7 @@ libc_hidden_def(wcrtomb)
/**********************************************************************/
#ifdef L_mbsrtowcs
-libc_hidden_proto(mbsnrtowcs)
-libc_hidden_proto(mbsrtowcs)
size_t mbsrtowcs(wchar_t *__restrict dst, const char **__restrict src,
size_t len, mbstate_t *__restrict ps)
{
@@ -393,9 +383,7 @@ libc_hidden_def(mbsrtowcs)
* TODO: Check for valid state anyway? */
-libc_hidden_proto(wcsnrtombs)
-libc_hidden_proto(wcsrtombs)
size_t wcsrtombs(char *__restrict dst, const wchar_t **__restrict src,
size_t len, mbstate_t *__restrict ps)
{
@@ -488,7 +476,8 @@ size_t attribute_hidden _wchar_utf8sntowcs(wchar_t *__restrict pwc, size_t wn,
#ifdef __UCLIBC_MJN3_ONLY__
#warning TODO: Fix range for 16 bit wchar_t case.
#endif
- if ( ((unsigned char)(s[-1] - 0xc0)) < (0xfe - 0xc0) ) {
+ if (( ((unsigned char)(s[-1] - 0xc0)) < (0xfe - 0xc0) ) &&
+ (((unsigned char)s[-1] != 0xc0 ) && ((unsigned char)s[-1] != 0xc1 ))) {
goto START;
}
BAD:
@@ -613,7 +602,7 @@ size_t attribute_hidden _wchar_wcsntoutf8s(char *__restrict s, size_t n,
if (!s) {
n = SIZE_MAX;
}
- s = buf;
+ s = buf;
store = 0;
}
@@ -699,7 +688,6 @@ size_t attribute_hidden _wchar_wcsntoutf8s(char *__restrict s, size_t n,
/* WARNING: We treat len as SIZE_MAX when dst is NULL! */
-libc_hidden_proto(mbsnrtowcs)
size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
size_t NMC, size_t len, mbstate_t *__restrict ps)
{
@@ -751,8 +739,8 @@ size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
while (count) {
if ((wc = ((unsigned char)(*s))) >= 0x80) { /* Non-ASCII... */
wc -= 0x80;
- wc = __UCLIBC_CURLOCALE_DATA.tbl8c2wc[
- (__UCLIBC_CURLOCALE_DATA.idx8c2wc[wc >> Cc2wc_IDX_SHIFT]
+ wc = __UCLIBC_CURLOCALE->tbl8c2wc[
+ (__UCLIBC_CURLOCALE->idx8c2wc[wc >> Cc2wc_IDX_SHIFT]
<< Cc2wc_IDX_SHIFT) + (wc & (Cc2wc_ROW_LEN - 1))];
if (!wc) {
goto BAD;
@@ -809,7 +797,6 @@ libc_hidden_def(mbsnrtowcs)
/* Note: We completely ignore ps in all currently supported conversions.
* TODO: Check for valid state anyway? */
-libc_hidden_proto(wcsnrtombs)
size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,
size_t NWC, size_t len, mbstate_t *__restrict ps)
{
@@ -862,12 +849,12 @@ size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,
} else {
u = 0;
if (wc <= Cwc2c_DOMAIN_MAX) {
- u = __UCLIBC_CURLOCALE_DATA.idx8wc2c[wc >> (Cwc2c_TI_SHIFT
+ u = __UCLIBC_CURLOCALE->idx8wc2c[wc >> (Cwc2c_TI_SHIFT
+ Cwc2c_TT_SHIFT)];
- u = __UCLIBC_CURLOCALE_DATA.tbl8wc2c[(u << Cwc2c_TI_SHIFT)
+ u = __UCLIBC_CURLOCALE->tbl8wc2c[(u << Cwc2c_TI_SHIFT)
+ ((wc >> Cwc2c_TT_SHIFT)
& ((1 << Cwc2c_TI_SHIFT)-1))];
- u = __UCLIBC_CURLOCALE_DATA.tbl8wc2c[Cwc2c_TI_LEN
+ u = __UCLIBC_CURLOCALE->tbl8wc2c[Cwc2c_TI_LEN
+ (u << Cwc2c_TT_SHIFT)
+ (wc & ((1 << Cwc2c_TT_SHIFT)-1))];
}
@@ -923,7 +910,6 @@ libc_hidden_def(wcsnrtombs)
/**********************************************************************/
#ifdef L_wcswidth
-libc_hidden_proto(wcswidth)
#ifdef __UCLIBC_MJN3_ONLY__
#warning REMINDER: If we start doing translit, wcwidth and wcswidth will need updating.
@@ -1039,13 +1025,12 @@ static const signed char new_wtbl[] = {
0, 2, 1, 2, 1, 0, 1,
};
-libc_hidden_proto(wcsnrtombs)
int wcswidth(const wchar_t *pwcs, size_t n)
{
- int h, l, m, count;
- wchar_t wc;
- unsigned char b;
+ int h, l, m, count;
+ wchar_t wc;
+ unsigned char b;
if (ENCODING == __ctype_encoding_7_bit) {
size_t i;
@@ -1081,7 +1066,7 @@ int wcswidth(const wchar_t *pwcs, size_t n)
}
#endif /* __CTYPE_HAS_UTF_8_LOCALES */
- for (count = 0 ; n && (wc = *pwcs++) ; n--) {
+ for (count = 0 ; n && (wc = *pwcs++) ; n--) {
if (wc <= 0xff) {
/* If we're here, wc != 0. */
if ((wc < 32) || ((wc >= 0x7f) && (wc < 0xa0))) {
@@ -1131,9 +1116,9 @@ int wcswidth(const wchar_t *pwcs, size_t n)
}
++count;
- }
+ }
- return count;
+ return count;
}
#else /* __UCLIBC_HAS_LOCALE__ */
@@ -1142,8 +1127,15 @@ int wcswidth(const wchar_t *pwcs, size_t n)
{
int count;
wchar_t wc;
+ size_t i;
- for (count = 0 ; n && (wc = *pwcs++) ; n--) {
+ for (i = 0 ; (i < n) && pwcs[i] ; i++) {
+ if (pwcs[i] != (pwcs[i] & 0x7f)) {
+ return -1;
+ }
+ }
+
+ for (count = 0 ; n && (wc = *pwcs++) ; n--) {
if (wc <= 0xff) {
/* If we're here, wc != 0. */
if ((wc < 32) || ((wc >= 0x7f) && (wc < 0xa0))) {
@@ -1167,11 +1159,10 @@ libc_hidden_def(wcswidth)
/**********************************************************************/
#ifdef L_wcwidth
-libc_hidden_proto(wcswidth)
int wcwidth(wchar_t wc)
{
- return wcswidth(&wc, 1);
+ return wcswidth(&wc, 1);
}
#endif
@@ -1191,45 +1182,6 @@ typedef struct {
int skip_invalid_input; /* To support iconv -c option. */
} _UC_iconv_t;
-
-
-#ifdef L_iconv
-
-#include <iconv.h>
-#include <string.h>
-#include <endian.h>
-#include <byteswap.h>
-
-#if (__BYTE_ORDER != __BIG_ENDIAN) && (__BYTE_ORDER != __LITTLE_ENDIAN)
-#error unsupported endianness for iconv
-#endif
-
-#ifndef __CTYPE_HAS_8_BIT_LOCALES
-#error currently iconv requires 8 bit locales
-#endif
-#ifndef __CTYPE_HAS_UTF_8_LOCALES
-#error currently iconv requires UTF-8 locales
-#endif
-
-
-enum {
- IC_WCHAR_T = 0xe0,
- IC_MULTIBYTE = 0xe0,
-#if __BYTE_ORDER == __BIG_ENDIAN
- IC_UCS_4 = 0xec,
- IC_UTF_32 = 0xe4,
- IC_UCS_2 = 0xe2,
- IC_UTF_16 = 0xea,
-#else
- IC_UCS_4 = 0xed,
- IC_UTF_32 = 0xe5,
- IC_UCS_2 = 0xe3,
- IC_UTF_16 = 0xeb,
-#endif
- IC_UTF_8 = 2,
- IC_ASCII = 1
-};
-
/* For the multibyte
* bit 0 means swap endian
* bit 1 means 2 byte
@@ -1237,15 +1189,23 @@ enum {
*
*/
+#if defined L_iconv && defined _LIBC
+/* Used externally only by iconv utility */
extern const unsigned char __iconv_codesets[];
libc_hidden_proto(__iconv_codesets)
+#endif
+
+#if defined L_iconv || defined L_iconv_main
+# ifdef L_iconv_main
+static
+# endif
const unsigned char __iconv_codesets[] =
"\x0a\xe0""WCHAR_T\x00" /* superset of UCS-4 but platform-endian */
#if __BYTE_ORDER == __BIG_ENDIAN
"\x08\xec""UCS-4\x00" /* always BE */
"\x0a\xec""UCS-4BE\x00"
"\x0a\xed""UCS-4LE\x00"
- "\x09\fe4""UTF-32\x00" /* platform endian with BOM */
+ "\x09\xe4""UTF-32\x00" /* platform endian with BOM */
"\x0b\xe4""UTF-32BE\x00"
"\x0b\xe5""UTF-32LE\x00"
"\x08\xe2""UCS-2\x00" /* always BE */
@@ -1271,17 +1231,57 @@ const unsigned char __iconv_codesets[] =
"\x08\x02""UTF-8\x00"
"\x0b\x01""US-ASCII\x00"
"\x07\x01""ASCII"; /* Must be last! (special case to save a nul) */
+#endif
+#if defined L_iconv && defined _LIBC
libc_hidden_data_def(__iconv_codesets)
+#endif
+
+
+#ifdef L_iconv
+
+#include <iconv.h>
+#include <string.h>
+#include <endian.h>
+#include <byteswap.h>
+
+#if (__BYTE_ORDER != __BIG_ENDIAN) && (__BYTE_ORDER != __LITTLE_ENDIAN)
+#error unsupported endianness for iconv
+#endif
+
+#ifndef __CTYPE_HAS_8_BIT_LOCALES
+#error currently iconv requires 8 bit locales
+#endif
+#ifndef __CTYPE_HAS_UTF_8_LOCALES
+#error currently iconv requires UTF-8 locales
+#endif
+
+
+enum {
+ IC_WCHAR_T = 0xe0,
+ IC_MULTIBYTE = 0xe0,
+#if __BYTE_ORDER == __BIG_ENDIAN
+ IC_UCS_4 = 0xec,
+ IC_UTF_32 = 0xe4,
+ IC_UCS_2 = 0xe2,
+ IC_UTF_16 = 0xea,
+#else
+ IC_UCS_4 = 0xed,
+ IC_UTF_32 = 0xe5,
+ IC_UCS_2 = 0xe3,
+ IC_UTF_16 = 0xeb,
+#endif
+ IC_UTF_8 = 2,
+ IC_ASCII = 1
+};
-/* Experimentally off - libc_hidden_proto(strcasecmp) */
static int find_codeset(const char *name)
{
const unsigned char *s;
int codeset;
- for (s = __iconv_codesets ; *s ; s += *s) {
- if (!strcasecmp(s+2, name)) {
+ for (s = __iconv_codesets; *s; s += *s) {
+ if (!strcasecmp((char*) (s + 2), name)) {
return s[1];
}
}
@@ -1291,7 +1291,7 @@ static int find_codeset(const char *name)
/* TODO: maybe CODESET_LIST + *s ??? */
/* 7bit is 1, UTF-8 is 2, 8-bit is >= 3 */
codeset = 2;
- s = __LOCALE_DATA_CODESET_LIST;
+ s = (const unsigned char *) __LOCALE_DATA_CODESET_LIST;
do {
++codeset; /* Increment codeset first. */
if (!strcasecmp(__LOCALE_DATA_CODESET_LIST+*s, name)) {
@@ -1311,9 +1311,9 @@ iconv_t weak_function iconv_open(const char *tocode, const char *fromcode)
&& ((fromcodeset = find_codeset(fromcode)) != 0)) {
if ((px = malloc(sizeof(_UC_iconv_t))) != NULL) {
px->tocodeset = tocodeset;
- px->tobom0 = px->tobom = (tocodeset & 0x10) >> 4;
+ px->tobom0 = px->tobom = (tocodeset >= 0xe0) ? (tocodeset & 0x10) >> 4 : 0;
px->fromcodeset0 = px->fromcodeset = fromcodeset;
- px->frombom0 = px->frombom = (fromcodeset & 0x10) >> 4;
+ px->frombom0 = px->frombom = (fromcodeset >= 0xe0) ? (fromcodeset & 0x10) >> 4 : 0;
px->skip_invalid_input = px->tostate.__mask
= px->fromstate.__mask = 0;
return (iconv_t) px;
@@ -1458,7 +1458,7 @@ size_t weak_function iconv(iconv_t cd, char **__restrict inbuf,
const __codeset_8_bit_t *c8b
= __locale_mmap->codeset_8_bit + px->fromcodeset - 3;
wc -= 0x80;
- wc = __UCLIBC_CURLOCALE_DATA.tbl8c2wc[
+ wc = __UCLIBC_CURLOCALE->tbl8c2wc[
(c8b->idx8c2wc[wc >> Cc2wc_IDX_SHIFT]
<< Cc2wc_IDX_SHIFT) + (wc & (Cc2wc_ROW_LEN - 1))];
if (!wc) {
@@ -1543,10 +1543,10 @@ size_t weak_function iconv(iconv_t cd, char **__restrict inbuf,
= __locale_mmap->codeset_8_bit + px->tocodeset - 3;
__uwchar_t u;
u = c8b->idx8wc2c[wc >> (Cwc2c_TI_SHIFT + Cwc2c_TT_SHIFT)];
- u = __UCLIBC_CURLOCALE_DATA.tbl8wc2c[(u << Cwc2c_TI_SHIFT)
+ u = __UCLIBC_CURLOCALE->tbl8wc2c[(u << Cwc2c_TI_SHIFT)
+ ((wc >> Cwc2c_TT_SHIFT)
& ((1 << Cwc2c_TI_SHIFT)-1))];
- wc = __UCLIBC_CURLOCALE_DATA.tbl8wc2c[Cwc2c_TI_LEN
+ wc = __UCLIBC_CURLOCALE->tbl8wc2c[Cwc2c_TI_LEN
+ (u << Cwc2c_TT_SHIFT)
+ (wc & ((1 << Cwc2c_TT_SHIFT)-1))];
if (wc) {
@@ -1565,172 +1565,4 @@ size_t weak_function iconv(iconv_t cd, char **__restrict inbuf,
}
return nrcount;
}
-
#endif
-/**********************************************************************/
-#ifdef L_iconv_main
-
-#include <string.h>
-#include <iconv.h>
-#include <stdarg.h>
-#include <libgen.h>
-
-extern const unsigned char __iconv_codesets[];
-
-#define IBUF BUFSIZ
-#define OBUF BUFSIZ
-
-char *progname;
-int hide_errors;
-
-static void error_msg(const char *fmt, ...)
- __attribute__ ((noreturn, format (printf, 1, 2)));
-
-static void error_msg(const char *fmt, ...)
-{
- va_list arg;
-
- if (!hide_errors) {
- fprintf(stderr, "%s: ", progname);
- va_start(arg, fmt);
- vfprintf(stderr, fmt, arg);
- va_end(arg);
- }
-
- exit(EXIT_FAILURE);
-}
-
-int main(int argc, char **argv)
-{
- FILE *ifile;
- FILE *ofile = stdout;
- const char *p;
- const char *s;
- static const char opt_chars[] = "tfocsl";
- /* 012345 */
- const char *opts[sizeof(opt_chars)]; /* last is infile name */
- iconv_t ic;
- char ibuf[IBUF];
- char obuf[OBUF];
- char *pi;
- char *po;
- size_t ni, no, r, pos;
-
- hide_errors = 0;
-
- for (s = opt_chars ; *s ; s++) {
- opts[ s - opt_chars ] = NULL;
- }
-
- progname = *argv;
- while (--argc) {
- p = *++argv;
- if ((*p != '-') || (*++p == 0)) {
- break;
- }
- do {
- if ((s = strchr(opt_chars,*p)) == NULL) {
- USAGE:
- s = basename(progname);
- fprintf(stderr,
- "%s [-cs] -f fromcode -t tocode [-o outputfile] [inputfile ...]\n"
- " or\n%s -l\n", s, s);
- return EXIT_FAILURE;
- }
- if ((s - opt_chars) < 3) {
- if ((--argc == 0) || opts[s - opt_chars]) {
- goto USAGE;
- }
- opts[s - opt_chars] = *++argv;
- } else {
- opts[s - opt_chars] = p;
- }
- } while (*++p);
- }
-
- if (opts[5]) { /* -l */
- fprintf(stderr, "Recognized codesets:\n");
- for (s = __iconv_codesets ; *s ; s += *s) {
- fprintf(stderr," %s\n", s+2);
- }
- s = __LOCALE_DATA_CODESET_LIST;
- do {
- fprintf(stderr," %s\n", __LOCALE_DATA_CODESET_LIST+ (unsigned char)(*s));
- } while (*++s);
-
- return EXIT_SUCCESS;
- }
-
- if (opts[4]) {
- hide_errors = 1;
- }
-
- if (!opts[0] || !opts[1]) {
- goto USAGE;
- }
- if ((ic = iconv_open(opts[0],opts[1])) == ((iconv_t)(-1))) {
- error_msg( "unsupported codeset in %s -> %s conversion\n", opts[0], opts[1]);
- }
- if (opts[3]) { /* -c */
- ((_UC_iconv_t *) ic)->skip_invalid_input = 1;
- }
-
- if ((s = opts[2]) != NULL) {
- if (!(ofile = fopen(s, "w"))) {
- error_msg( "couldn't open %s for writing\n", s);
- }
- }
-
- pos = ni = 0;
- do {
- if (!argc || ((**argv == '-') && !((*argv)[1]))) {
- ifile = stdin; /* we don't check for duplicates */
- } else if (!(ifile = fopen(*argv, "r"))) {
- error_msg( "couldn't open %s for reading\n", *argv);
- }
-
- while ((r = fread(ibuf + ni, 1, IBUF - ni, ifile)) > 0) {
- pos += r;
- ni += r;
- no = OBUF;
- pi = ibuf;
- po = obuf;
- if ((r = iconv(ic, &pi, &ni, &po, &no)) == ((size_t)(-1))) {
- if ((errno != EINVAL) && (errno != E2BIG)) {
- error_msg( "iconv failed at pos %lu : %m\n", (unsigned long) (pos - ni));
- }
- }
- if ((r = OBUF - no) > 0) {
- if (fwrite(obuf, 1, OBUF - no, ofile) < r) {
- error_msg( "write error\n");
- }
- }
- if (ni) { /* still bytes in buffer! */
- memmove(ibuf, pi, ni);
- }
- }
-
- if (ferror(ifile)) {
- error_msg( "read error\n");
- }
-
- ++argv;
-
- if (ifile != stdin) {
- fclose(ifile);
- }
-
- } while (--argc > 0);
-
- iconv_close(ic);
-
- if (ni) {
- error_msg( "incomplete sequence\n");
- }
-
- return (((_UC_iconv_t *) ic)->skip_invalid_input < 2)
- ? EXIT_SUCCESS : EXIT_FAILURE;
-}
-
-#endif
-/**********************************************************************/
diff --git a/libc/misc/wctype/Makefile.in b/libc/misc/wctype/Makefile.in
index f4210ebb0..d40c2d321 100644
--- a/libc/misc/wctype/Makefile.in
+++ b/libc/misc/wctype/Makefile.in
@@ -1,10 +1,12 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
+subdirs += libc/misc/wctype
+
# multi source _wctype.c
COM_SRC := \
iswalnum.c iswalpha.c iswcntrl.c iswdigit.c iswgraph.c \
@@ -12,23 +14,19 @@ COM_SRC := \
iswxdigit.c iswblank.c wctrans.c towctrans.c \
wctype.c iswctype.c towlower.c towupper.c
-CSRC :=
-ifeq ($(UCLIBC_HAS_WCHAR),y)
-CSRC += $(COM_SRC)
-endif
-ifeq ($(UCLIBC_HAS_XLOCALE),y)
-CSRC += $(patsubst %.c,%_l.c,$(COM_SRC))
-endif
+CSRC-y :=
+CSRC-$(UCLIBC_HAS_WCHAR) += $(COM_SRC)
+CSRC-$(UCLIBC_HAS_XLOCALE) += $(patsubst %.c,%_l.c,$(COM_SRC))
MISC_WCTYPE_DIR := $(top_srcdir)libc/misc/wctype
MISC_WCTYPE_OUT := $(top_builddir)libc/misc/wctype
-MISC_WCTYPE_SRC := $(patsubst %.c,$(MISC_WCTYPE_DIR)/%.c,$(CSRC))
-MISC_WCTYPE_OBJ := $(patsubst %.c,$(MISC_WCTYPE_OUT)/%.o,$(CSRC))
+MISC_WCTYPE_SRC := $(patsubst %.c,$(MISC_WCTYPE_DIR)/%.c,$(CSRC-y))
+MISC_WCTYPE_OBJ := $(patsubst %.c,$(MISC_WCTYPE_OUT)/%.o,$(CSRC-y))
libc-y += $(MISC_WCTYPE_OBJ)
-objclean-y += misc_wctype_objclean
+objclean-y += CLEAN_libc/misc/wctype
-misc_wctype_objclean:
- $(RM) $(MISC_WCTYPE_OUT)/*.{o,os}
+CLEAN_libc/misc/wctype:
+ $(do_rm) $(addprefix $(MISC_WCTYPE_OUT)/*., o os)
diff --git a/libc/misc/wctype/_wctype.c b/libc/misc/wctype/_wctype.c
index 25419b500..68fae8b54 100644
--- a/libc/misc/wctype/_wctype.c
+++ b/libc/misc/wctype/_wctype.c
@@ -11,8 +11,8 @@
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
*/
/* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
@@ -37,31 +37,8 @@
#include <stdint.h>
#include <bits/uClibc_uwchar.h>
-/* Experimentally off - libc_hidden_proto(strcmp) */
-libc_hidden_proto(tolower)
-libc_hidden_proto(toupper)
-libc_hidden_proto(towlower)
-libc_hidden_proto(towupper)
-libc_hidden_proto(towctrans)
-libc_hidden_proto(iswctype)
-
#if defined(__LOCALE_C_ONLY) && defined(__UCLIBC_DO_XLOCALE)
-#error xlocale functionality is not supported in stub locale mode.
-#endif
-
-#ifdef __UCLIBC_HAS_XLOCALE__
-#include <xlocale.h>
-libc_hidden_proto(towlower_l)
-libc_hidden_proto(towupper_l)
-libc_hidden_proto(towctrans_l)
-libc_hidden_proto(iswctype_l)
-#elif defined __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__ctype_b)
-#endif /* __UCLIBC_HAS_XLOCALE__ */
-
-#ifdef __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__C_ctype_tolower)
-libc_hidden_proto(__C_ctype_toupper)
+# error xlocale functionality is not supported in stub locale mode.
#endif
/* We know wide char support is enabled. We wouldn't be here otherwise. */
@@ -70,43 +47,9 @@ libc_hidden_proto(__C_ctype_toupper)
* towctrans function. */
/* #define SMALL_UPLOW */
-/**********************************************************************/
-#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_iswspace
-/* generates one warning */
-#warning TODO: Fix the __CTYPE_* codes!
-#endif
-#endif /* __UCLIBC_MJN3_ONLY__ */
-
-#if 1
-/* Taking advantage of the C99 mutual-exclusion guarantees for the various
- * (w)ctype classes, including the descriptions of printing and control
- * (w)chars, we can place each in one of the following mutually-exlusive
- * subsets. Since there are less than 16, we can store the data for
- * each (w)chars in a nibble. In contrast, glibc uses an unsigned int
- * per (w)char, with one bit flag for each is* type. While this allows
- * a simple '&' operation to determine the type vs. a range test and a
- * little special handling for the "blank" and "xdigit" types in my
- * approach, it also uses 8 times the space for the tables on the typical
- * 32-bit archs we supported.*/
-enum {
- __CTYPE_unclassified = 0,
- __CTYPE_alpha_nonupper_nonlower,
- __CTYPE_alpha_lower,
- __CTYPE_alpha_upper_lower,
- __CTYPE_alpha_upper,
- __CTYPE_digit,
- __CTYPE_punct,
- __CTYPE_graph,
- __CTYPE_print_space_nonblank,
- __CTYPE_print_space_blank,
- __CTYPE_space_nonblank_noncntrl,
- __CTYPE_space_blank_noncntrl,
- __CTYPE_cntrl_space_nonblank,
- __CTYPE_cntrl_space_blank,
- __CTYPE_cntrl_nonspace
-};
-#endif
+
+/* Pull in __CTYPE_xxx constants */
+#include <bits/uClibc_charclass.h>
/* The following is used to implement wctype(), but it is defined
@@ -151,18 +94,18 @@ enum {
/*--------------------------------------------------------------------*/
#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_iswspace
+# ifdef L_iswspace
/* generates one warning */
-#warning TODO: Fix WC* defines!
+# warning TODO: Fix WC* defines!
+# endif
#endif
-#endif /* __UCLIBC_MJN3_ONLY__ */
-#define ENCODING ((__UCLIBC_CURLOCALE_DATA).encoding)
+#define ENCODING (__UCLIBC_CURLOCALE->encoding)
-#define WCctype ((__UCLIBC_CURLOCALE_DATA).tblwctype)
-#define WCuplow ((__UCLIBC_CURLOCALE_DATA).tblwuplow)
-#define WCcmob ((__UCLIBC_CURLOCALE_DATA).tblwcomb)
-#define WCuplow_diff ((__UCLIBC_CURLOCALE_DATA).tblwuplow_diff)
+#define WCctype (__UCLIBC_CURLOCALE->tblwctype)
+#define WCuplow (__UCLIBC_CURLOCALE->tblwuplow)
+#define WCcmob (__UCLIBC_CURLOCALE->tblwcomb)
+#define WCuplow_diff (__UCLIBC_CURLOCALE->tblwuplow_diff)
#define WC_TABLE_DOMAIN_MAX __LOCALE_DATA_WC_TABLE_DOMAIN_MAX
@@ -193,28 +136,27 @@ enum {
#ifdef __UCLIBC_DO_XLOCALE
#define ISW_FUNC_BODY(NAME) \
-libc_hidden_proto(__PASTE3(isw,NAME,_l)); \
int __PASTE3(isw,NAME,_l) (wint_t wc, __locale_t l) \
{ \
return iswctype_l(wc, __PASTE2(_CTYPE_is,NAME), l); \
-} \
-libc_hidden_def(__PASTE3(isw,NAME,_l))
+}
#else /* __UCLIBC_DO_XLOCALE */
#define ISW_FUNC_BODY(NAME) \
-libc_hidden_proto(__PASTE2(isw,NAME)); \
int __PASTE2(isw,NAME) (wint_t wc) \
{ \
return iswctype(wc, __PASTE2(_CTYPE_is,NAME)); \
-} \
-libc_hidden_def(__PASTE2(isw,NAME))
+}
#endif /* __UCLIBC_DO_XLOCALE */
/**********************************************************************/
#if defined(L_iswalnum) || defined(L_iswalnum_l)
ISW_FUNC_BODY(alnum);
+# ifdef L_iswalnum
+libc_hidden_def(iswalnum)
+# endif
#endif
/**********************************************************************/
@@ -251,6 +193,9 @@ ISW_FUNC_BODY(graph);
#if defined(L_iswlower) || defined(L_iswlower_l)
ISW_FUNC_BODY(lower);
+# ifdef L_iswlower
+libc_hidden_def(iswlower)
+# endif
#endif
/**********************************************************************/
@@ -269,12 +214,20 @@ ISW_FUNC_BODY(punct);
#if defined(L_iswspace) || defined(L_iswspace_l)
ISW_FUNC_BODY(space);
+# ifdef L_iswspace
+libc_hidden_def(iswspace)
+# else
+libc_hidden_def(iswspace_l)
+# endif
#endif
/**********************************************************************/
#if defined(L_iswupper) || defined(L_iswupper_l)
ISW_FUNC_BODY(upper);
+# ifdef L_iswupper
+libc_hidden_def(iswupper)
+# endif
#endif
/**********************************************************************/
@@ -286,72 +239,66 @@ ISW_FUNC_BODY(xdigit);
/**********************************************************************/
#if defined(L_towlower) || defined(L_towlower_l)
-#ifdef L_towlower
-#define TOWLOWER(w) towlower(w)
-#else /* L_towlower */
-#define TOWLOWER(w) towlower_l(w, __locale_t locale)
-#undef __UCLIBC_CURLOCALE_DATA
-#undef __UCLIBC_CURLOCALE
-#define __UCLIBC_CURLOCALE_DATA (*locale)
-#define __UCLIBC_CURLOCALE (locale)
-#endif /* L_towlower */
+# ifdef L_towlower
+# define TOWLOWER(w) towlower(w)
+# else
+# define TOWLOWER(w) towlower_l(w, __locale_t locale)
+# undef __UCLIBC_CURLOCALE
+# define __UCLIBC_CURLOCALE (locale)
+# endif
-#ifdef __UCLIBC_HAS_XLOCALE__
-#define TOWCTRANS(w,d) towctrans_l(w,d, __UCLIBC_CURLOCALE)
-#else /* __UCLIBC_HAS_XLOCALE__ */
-#define TOWCTRANS(w,d) towctrans(w,d)
-#endif /* __UCLIBC_HAS_XLOCALE__ */
+# ifdef __UCLIBC_HAS_XLOCALE__
+# define TOWCTRANS(w,d) towctrans_l(w,d, __UCLIBC_CURLOCALE)
+# else
+# define TOWCTRANS(w,d) towctrans(w,d)
+# endif
-#define __C_towlower(wc) \
- ((((__uwchar_t)(wc)) <= 0x7f) ? (__C_ctype_tolower)[(wc)] : (wc))
+# define __C_towlower(wc) \
+ (((__uwchar_t)(wc) <= 0x7f) ? (__C_ctype_tolower)[(wc)] : (wc))
-#ifdef __LOCALE_C_ONLY
+# ifdef __LOCALE_C_ONLY
wint_t towlower(wint_t wc)
{
-#ifdef __UCLIBC_HAS_CTYPE_TABLES__
+# ifdef __UCLIBC_HAS_CTYPE_TABLES__
return __C_towlower(wc);
-#else
- return (wc == ((unsigned int)(wc)))
- ? __C_tolower(((unsigned int)(wc)))
+# else
+ return (wc == (unsigned)wc)
+ ? __C_tolower((unsigned)wc)
: 0;
-#endif
+# endif
}
-#else /* __LOCALE_C_ONLY */
+# else /* __LOCALE_C_ONLY */
-#ifdef SMALL_UPLOW
-
-#if defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__)
+# ifdef SMALL_UPLOW
+# if defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__)
wint_t towlower(wint_t wc)
{
return towctrans_l(wc, _CTYPE_tolower, __UCLIBC_CURLOCALE);
}
-
-#else /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
-
+# else /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
wint_t TOWLOWER(wint_t wc)
{
return TOWCTRANS(wc, _CTYPE_tolower);
}
+# endif /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
-#endif /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
+# else /* SMALL_UPLOW */
-#else /* SMALL_UPLOW */
-
-#if defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__)
+# if defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__)
wint_t towlower(wint_t wc)
{
return towlower_l(wc, __UCLIBC_CURLOCALE);
}
-#else /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
+# else /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
wint_t TOWLOWER(wint_t wc)
{
- unsigned int sc, n, i;
+ unsigned sc, n, i;
__uwchar_t u = wc;
if (ENCODING == __ctype_encoding_7_bit) {
@@ -365,101 +312,89 @@ wint_t TOWLOWER(wint_t wc)
n = u & ((1 << WCuplow_II_SHIFT) - 1);
u >>= WCuplow_II_SHIFT;
- i = ((unsigned int) WCuplow[u]) << WCuplow_II_SHIFT;
- i = ((unsigned int) WCuplow[WCuplow_II_LEN + i + n])
- << WCuplow_TI_SHIFT;
- i = ((unsigned int) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN
- + i + sc]) << 1;
+ i = ((unsigned) WCuplow[u]) << WCuplow_II_SHIFT;
+ i = ((unsigned) WCuplow[WCuplow_II_LEN + i + n]) << WCuplow_TI_SHIFT;
+ i = ((unsigned) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN + i + sc]) << 1;
wc += WCuplow_diff[i + 1];
}
return wc;
}
-#endif /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
+# endif /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
-#endif /* SMALL_UPLOW */
+# endif /* SMALL_UPLOW */
-#ifdef L_towlower_l
+# ifdef L_towlower_l
libc_hidden_def(towlower_l)
-#endif /* L_towlower_l */
+# endif
-#endif /* __LOCALE_C_ONLY */
+# endif /* __LOCALE_C_ONLY */
-#ifndef L_towlower_l
+# ifndef L_towlower_l
libc_hidden_def(towlower)
-#endif
+# endif
#endif
/**********************************************************************/
#if defined(L_towupper) || defined(L_towupper_l)
-#ifdef L_towupper
-#define TOWUPPER(w) towupper(w)
-#else /* L_towupper */
-#define TOWUPPER(w) towupper_l(w, __locale_t locale)
-#undef __UCLIBC_CURLOCALE_DATA
-#undef __UCLIBC_CURLOCALE
-#define __UCLIBC_CURLOCALE_DATA (*locale)
-#define __UCLIBC_CURLOCALE (locale)
-#endif /* L_towupper */
+# ifdef L_towupper
+# define TOWUPPER(w) towupper(w)
+# else
+# define TOWUPPER(w) towupper_l(w, __locale_t locale)
+# undef __UCLIBC_CURLOCALE
+# define __UCLIBC_CURLOCALE (locale)
+# endif
-#ifdef __UCLIBC_HAS_XLOCALE__
-#define TOWCTRANS(w,d) towctrans_l(w,d, __UCLIBC_CURLOCALE)
-#else /* __UCLIBC_HAS_XLOCALE__ */
-#define TOWCTRANS(w,d) towctrans(w,d)
-#endif /* __UCLIBC_HAS_XLOCALE__ */
+# ifdef __UCLIBC_HAS_XLOCALE__
+# define TOWCTRANS(w,d) towctrans_l(w,d, __UCLIBC_CURLOCALE)
+# else
+# define TOWCTRANS(w,d) towctrans(w,d)
+# endif
-#define __C_towupper(wc) \
- ((((__uwchar_t)(wc)) <= 0x7f) ? (__C_ctype_toupper)[(wc)] : (wc))
+# define __C_towupper(wc) \
+ (((__uwchar_t)(wc) <= 0x7f) ? (__C_ctype_toupper)[(wc)] : (wc))
-#ifdef __LOCALE_C_ONLY
+# ifdef __LOCALE_C_ONLY
wint_t towupper(wint_t wc)
{
-#ifdef __UCLIBC_HAS_CTYPE_TABLES__
+# ifdef __UCLIBC_HAS_CTYPE_TABLES__
return __C_towupper(wc);
-#else
- return (wc == ((unsigned int)(wc)))
- ? __C_toupper(((unsigned int)(wc)))
+# else
+ return (wc == (unsigned)wc)
+ ? __C_toupper((unsigned)wc)
: 0;
-#endif
-
+# endif
}
-#else /* __LOCALE_C_ONLY */
-
-#ifdef SMALL_UPLOW
+# else /* __LOCALE_C_ONLY */
-#if defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__)
+# ifdef SMALL_UPLOW
+# if defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__)
wint_t towupper(wint_t wc)
{
return towctrans_l(wc, _CTYPE_toupper, __UCLIBC_CURLOCALE);
}
-
-#else /* defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__) */
-
+# else
wint_t TOWUPPER(wint_t wc)
{
return TOWCTRANS(wc, _CTYPE_toupper);
}
+# endif
-#endif /* defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__) */
-
-#else /* SMALL_UPLOW */
-
-#if defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__)
+# else /* SMALL_UPLOW */
+# if defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__)
wint_t towupper(wint_t wc)
{
return towupper_l(wc, __UCLIBC_CURLOCALE);
}
-
-#else /* defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__) */
-
+# else /* defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__) */
wint_t TOWUPPER(wint_t wc)
{
- unsigned int sc, n, i;
+ unsigned sc, n, i;
__uwchar_t u = wc;
if (ENCODING == __ctype_encoding_7_bit) {
@@ -473,38 +408,33 @@ wint_t TOWUPPER(wint_t wc)
n = u & ((1 << WCuplow_II_SHIFT) - 1);
u >>= WCuplow_II_SHIFT;
- i = ((unsigned int) WCuplow[u]) << WCuplow_II_SHIFT;
- i = ((unsigned int) WCuplow[WCuplow_II_LEN + i + n])
- << WCuplow_TI_SHIFT;
- i = ((unsigned int) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN
- + i + sc]) << 1;
+ i = ((unsigned) WCuplow[u]) << WCuplow_II_SHIFT;
+ i = ((unsigned) WCuplow[WCuplow_II_LEN + i + n]) << WCuplow_TI_SHIFT;
+ i = ((unsigned) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN + i + sc]) << 1;
wc += WCuplow_diff[i];
}
return wc;
}
+# endif /* defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__) */
-#endif /* defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__) */
+# endif /* SMALL_UPLOW */
-#endif /* SMALL_UPLOW */
-
-#ifdef L_towupper_l
+# ifdef L_towupper_l
libc_hidden_def(towupper_l)
-#endif /* L_towupper_l */
+# endif
-#endif /* __LOCALE_C_ONLY */
+# endif /* __LOCALE_C_ONLY */
-#ifndef L_towupper_l
+# ifndef L_towupper_l
libc_hidden_def(towupper)
-#endif
+# endif
#endif
/**********************************************************************/
#ifdef L_wctype
static const unsigned char typestring[] = __CTYPE_TYPESTRING;
-/* extern const unsigned char typestring[]; */
-libc_hidden_proto(wctype)
wctype_t wctype(const char *property)
{
const unsigned char *p;
@@ -513,7 +443,7 @@ wctype_t wctype(const char *property)
p = typestring;
i = 1;
do {
- if (!strcmp(property, ++p)) {
+ if (!strcmp(property, (const char *) ++p)) {
return i;
}
++i;
@@ -530,17 +460,13 @@ libc_hidden_def(wctype)
#ifdef L_wctype_l
#ifdef __UCLIBC_MJN3_ONLY__
-#warning REMINDER: Currently wctype_l simply calls wctype.
-#endif /* __UCLIBC_MJN3_ONLY__ */
-
-libc_hidden_proto(wctype)
+# warning REMINDER: Currently wctype_l simply calls wctype.
+#endif
-libc_hidden_proto(wctype_l)
wctype_t wctype_l (const char *property, __locale_t locale)
{
return wctype(property);
}
-libc_hidden_def(wctype_l)
#endif
/**********************************************************************/
@@ -548,24 +474,25 @@ libc_hidden_def(wctype_l)
#define __C_iswdigit(c) \
((sizeof(c) == sizeof(char)) \
- ? (((unsigned char)((c) - '0')) < 10) \
- : (((__uwchar_t)((c) - '0')) < 10))
+ ? ((unsigned char)((c) - '0') < 10) \
+ : ((__uwchar_t)((c) - '0') < 10) \
+ )
#define __C_iswxdigit(c) \
(__C_iswdigit(c) \
|| ((sizeof(c) == sizeof(char)) \
- ? (((unsigned char)((((c)) | 0x20) - 'a')) < 6) \
- : (((__uwchar_t)((((c)) | 0x20) - 'a')) < 6)))
+ ? ((unsigned char)(((c) | 0x20) - 'a') < 6) \
+ : ((__uwchar_t)(((c) | 0x20) - 'a') < 6) \
+ ) \
+ )
#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_iswctype
-#warning CONSIDER: Change to bit shift? would need to sync with wctype.h
+# ifdef L_iswctype
+# warning CONSIDER: Change to bit shift? would need to sync with wctype.h
+# endif
#endif
-#endif /* __UCLIBC_MJN3_ONLY__ */
-
#ifdef __UCLIBC_HAS_CTYPE_TABLES__
-#if !defined(__UCLIBC_HAS_XLOCALE__) || defined(L_iswctype_l)
-
+# if !defined(__UCLIBC_HAS_XLOCALE__) || defined(L_iswctype_l)
static const unsigned short int desc2flag[] = {
[_CTYPE_unclassified] = 0,
[_CTYPE_isalnum] = (unsigned short int) _ISwalnum,
@@ -581,9 +508,8 @@ static const unsigned short int desc2flag[] = {
[_CTYPE_isupper] = (unsigned short int) _ISwupper,
[_CTYPE_isxdigit] = (unsigned short int) _ISwxdigit,
};
-
-#endif /* defined(L_iswctype_L) || defined(__LOCALE_C_ONLY) */
-#endif /* __UCLIBC_HAS_CTYPE_TABLES__ */
+# endif
+#endif
#ifdef __LOCALE_C_ONLY
@@ -593,9 +519,9 @@ int iswctype(wint_t wc, wctype_t desc)
{
/* Note... wctype_t is unsigned. */
- if ((((__uwchar_t) wc) <= 0x7f)
- && (desc < (sizeof(desc2flag)/sizeof(desc2flag[0])))
- ) {
+ if ((__uwchar_t) wc <= 0x7f
+ && desc < (sizeof(desc2flag) / sizeof(desc2flag[0]))
+ ) {
return __isctype(wc, desc2flag[desc]);
}
return 0;
@@ -607,32 +533,32 @@ int iswctype(wint_t wc, wctype_t desc)
{
/* This is lame, but it is here just to get it working for now. */
- if (wc == ((unsigned int)(wc))) {
- switch(desc) {
+ if (wc == (unsigned)wc) {
+ switch (desc) {
case _CTYPE_isupper:
- return __C_isupper((unsigned int)(wc));
+ return __C_isupper((unsigned)wc);
case _CTYPE_islower:
- return __C_islower((unsigned int)(wc));
+ return __C_islower((unsigned)wc);
case _CTYPE_isalpha:
- return __C_isalpha((unsigned int)(wc));
+ return __C_isalpha((unsigned)wc);
case _CTYPE_isdigit:
- return __C_isdigit((unsigned int)(wc));
+ return __C_isdigit((unsigned)wc);
case _CTYPE_isxdigit:
- return __C_isxdigit((unsigned int)(wc));
+ return __C_isxdigit((unsigned)wc);
case _CTYPE_isspace:
- return __C_isspace((unsigned int)(wc));
+ return __C_isspace((unsigned)wc);
case _CTYPE_isprint:
- return __C_isprint((unsigned int)(wc));
+ return __C_isprint((unsigned)wc);
case _CTYPE_isgraph:
- return __C_isgraph((unsigned int)(wc));
+ return __C_isgraph((unsigned)wc);
case _CTYPE_isblank:
- return __C_isblank((unsigned int)(wc));
+ return __C_isblank((unsigned)wc);
case _CTYPE_iscntrl:
- return __C_iscntrl((unsigned int)(wc));
+ return __C_iscntrl((unsigned)wc);
case _CTYPE_ispunct:
- return __C_ispunct((unsigned int)(wc));
+ return __C_ispunct((unsigned)wc);
case _CTYPE_isalnum:
- return __C_isalnum((unsigned int)(wc));
+ return __C_isalnum((unsigned)wc);
default:
break;
}
@@ -645,20 +571,18 @@ int iswctype(wint_t wc, wctype_t desc)
#else /* __LOCALE_C_ONLY */
#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_iswctype
-#warning CONSIDER: Handle combining class?
+# ifdef L_iswctype
+# warning CONSIDER: Handle combining class?
+# endif
#endif
-#endif /* __UCLIBC_MJN3_ONLY__ */
#ifdef L_iswctype
-#define ISWCTYPE(w,d) iswctype(w,d)
-#else /* L_iswctype */
-#define ISWCTYPE(w,d) iswctype_l(w,d, __locale_t locale)
-#undef __UCLIBC_CURLOCALE_DATA
-#undef __UCLIBC_CURLOCALE
-#define __UCLIBC_CURLOCALE_DATA (*locale)
-#define __UCLIBC_CURLOCALE (locale)
-#endif /* L_iswctype */
+# define ISWCTYPE(w,d) iswctype(w,d)
+#else
+# define ISWCTYPE(w,d) iswctype_l(w,d, __locale_t locale)
+# undef __UCLIBC_CURLOCALE
+# define __UCLIBC_CURLOCALE (locale)
+#endif
#if defined(L_iswctype) && defined(__UCLIBC_HAS_XLOCALE__)
@@ -671,12 +595,12 @@ int iswctype(wint_t wc, wctype_t desc)
int ISWCTYPE(wint_t wc, wctype_t desc)
{
- unsigned int sc, n, i0, i1;
+ unsigned sc, n, i0, i1;
unsigned char d = __CTYPE_unclassified;
- if ((ENCODING != __ctype_encoding_7_bit) || (((__uwchar_t) wc) <= 0x7f)){
+ if ((ENCODING != __ctype_encoding_7_bit) || ((__uwchar_t)wc <= 0x7f)) {
if (desc < _CTYPE_iswxdigit) {
- if (((__uwchar_t) wc) <= WC_TABLE_DOMAIN_MAX) {
+ if ((__uwchar_t)wc <= WC_TABLE_DOMAIN_MAX) {
/* From here on, we know wc > 0. */
sc = wc & WCctype_TI_MASK;
wc >>= WCctype_TI_SHIFT;
@@ -690,26 +614,24 @@ int ISWCTYPE(wint_t wc, wctype_t desc)
d = WCctype[WCctype_II_LEN + WCctype_TI_LEN + i1 + (sc >> 1)];
d = (sc & 1) ? (d >> 4) : (d & 0xf);
- } else if ( ((((__uwchar_t)(wc - 0xe0020UL)) <= 0x5f)
- || (wc == 0xe0001UL))
- || ( (((__uwchar_t)(wc - 0xf0000UL)) < 0x20000UL)
- && ((wc & 0xffffU) <= 0xfffdU))
- ) {
+ } else if ((__uwchar_t)(wc - 0xe0020UL) <= 0x5f
+ || wc == 0xe0001UL
+ || (((__uwchar_t)(wc - 0xf0000UL) < 0x20000UL) && ((wc & 0xffffU) <= 0xfffdU))
+ ) {
d = __CTYPE_punct;
}
#if 0
- return ( ((unsigned char)(d - ctype_range[2*desc]))
- <= ctype_range[2*desc + 1] )
+ return ((unsigned char)(d - ctype_range[2*desc]) <= ctype_range[2*desc + 1])
&& ((desc != _CTYPE_iswblank) || (d & 1));
#else
- return (__UCLIBC_CURLOCALE_DATA).code2flag[d] & desc2flag[desc];
+ return __UCLIBC_CURLOCALE->code2flag[d] & desc2flag[desc];
#endif
}
#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: xdigit really needs to be handled better. Remember only for ascii!
-#endif /* __UCLIBC_MJN3_ONLY__ */
+# warning TODO: xdigit really needs to be handled better. Remember only for ascii!
+#endif
/* TODO - Add locale-specific classifications. */
return (desc == _CTYPE_iswxdigit) ? __C_iswxdigit(wc) : 0;
}
@@ -720,13 +642,13 @@ int ISWCTYPE(wint_t wc, wctype_t desc)
#ifdef L_iswctype_l
libc_hidden_def(iswctype_l)
-#endif /* L_iswctype_l */
+#endif
#endif /* __LOCALE_C_ONLY */
#ifdef L_iswctype
libc_hidden_def(iswctype)
-#endif /* L_iswctype */
+#endif
#endif
/**********************************************************************/
@@ -736,24 +658,23 @@ libc_hidden_def(iswctype)
/* Minimal support for C/POSIX locale. */
-#ifndef _tolower
-#warning _tolower is undefined!
-#define _tolower(c) tolower(c)
-#endif
-#ifndef _toupper
-#warning _toupper is undefined!
-#define _toupper(c) toupper(c)
-#endif
-
wint_t towctrans(wint_t wc, wctrans_t desc)
{
- if (((unsigned int)(desc - _CTYPE_tolower))
- <= (_CTYPE_toupper - _CTYPE_tolower)
- ) {
+ if ((unsigned)(desc - _CTYPE_tolower) <= (_CTYPE_toupper - _CTYPE_tolower)) {
/* Transliteration is either tolower or toupper. */
- if (((__uwchar_t) wc) <= 0x7f) {
+#if 0
+/* I think it's wrong: _toupper(c) assumes that c is a *lowercase* *letter* -
+ * it is defined as ((c) ^ 0x20)! */
+ if ((__uwchar_t) wc <= 0x7f) {
return (desc == _CTYPE_tolower) ? _tolower(wc) : _toupper(wc);
}
+#endif
+ __uwchar_t c = wc | 0x20; /* lowercase if it's a letter */
+ if (c >= 'a' && c <= 'z') {
+ if (desc == _CTYPE_toupper)
+ c &= ~0x20; /* uppercase */
+ return c;
+ }
} else {
__set_errno(EINVAL); /* Invalid transliteration. */
}
@@ -763,22 +684,20 @@ wint_t towctrans(wint_t wc, wctrans_t desc)
#else /* __LOCALE_C_ONLY */
#ifdef L_towctrans
-#define TOWCTRANS(w,d) towctrans(w,d)
-#else /* L_towctrans */
-#define TOWCTRANS(w,d) towctrans_l(w,d, __locale_t locale)
-#undef __UCLIBC_CURLOCALE_DATA
-#undef __UCLIBC_CURLOCALE
-#define __UCLIBC_CURLOCALE_DATA (*locale)
-#define __UCLIBC_CURLOCALE (locale)
-#endif /* L_towctrans */
+# define TOWCTRANS(w,d) towctrans(w,d)
+#else
+# define TOWCTRANS(w,d) towctrans_l(w,d, __locale_t locale)
+# undef __UCLIBC_CURLOCALE
+# define __UCLIBC_CURLOCALE (locale)
+#endif
#ifdef __UCLIBC_HAS_XLOCALE__
-#define TOWLOWER(w,l) towlower_l(w,l)
-#define TOWUPPER(w,l) towupper_l(w,l)
-#else /* __UCLIBC_HAS_XLOCALE__ */
-#define TOWLOWER(w,l) towlower(w)
-#define TOWUPPER(w,l) towupper(w)
-#endif /* __UCLIBC_HAS_XLOCALE__ */
+# define TOWLOWER(w,l) towlower_l(w,l)
+# define TOWUPPER(w,l) towupper_l(w,l)
+#else
+# define TOWLOWER(w,l) towlower(w)
+# define TOWUPPER(w,l) towupper(w)
+#endif
#if defined(L_towctrans) && defined(__UCLIBC_HAS_XLOCALE__)
@@ -793,48 +712,43 @@ wint_t towctrans(wint_t wc, wctrans_t desc)
wint_t TOWCTRANS(wint_t wc, wctrans_t desc)
{
- unsigned int sc, n, i;
+ unsigned sc, n, i;
__uwchar_t u = wc;
/* TODO - clean up */
if (ENCODING == __ctype_encoding_7_bit) {
- if ((((__uwchar_t) wc) > 0x7f)
- || (((unsigned int)(desc - _CTYPE_tolower))
- > (_CTYPE_toupper - _CTYPE_tolower))
- ){
+ if ((__uwchar_t)wc > 0x7f
+ || (unsigned)(desc - _CTYPE_tolower) > (_CTYPE_toupper - _CTYPE_tolower)
+ ) {
/* We're in the C/POSIX locale, so ignore non-ASCII values
* as well an any mappings other than toupper or tolower. */
return wc;
}
}
- if (((unsigned int)(desc - _CTYPE_tolower))
- <= (_CTYPE_totitle - _CTYPE_tolower)
- ) {
+ if ((unsigned)(desc - _CTYPE_tolower) <= (_CTYPE_totitle - _CTYPE_tolower)) {
if (u <= WC_TABLE_DOMAIN_MAX) {
sc = u & ((1 << WCuplow_TI_SHIFT) - 1);
u >>= WCuplow_TI_SHIFT;
n = u & ((1 << WCuplow_II_SHIFT) - 1);
u >>= WCuplow_II_SHIFT;
- i = ((unsigned int) WCuplow[u]) << WCuplow_II_SHIFT;
- i = ((unsigned int) WCuplow[WCuplow_II_LEN + i + n])
- << WCuplow_TI_SHIFT;
- i = ((unsigned int) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN
- + i + sc]) << 1;
+ i = ((unsigned) WCuplow[u]) << WCuplow_II_SHIFT;
+ i = ((unsigned) WCuplow[WCuplow_II_LEN + i + n]) << WCuplow_TI_SHIFT;
+ i = ((unsigned) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN + i + sc]) << 1;
if (desc == _CTYPE_tolower) {
++i;
}
wc += WCuplow_diff[i];
if (desc == _CTYPE_totitle) {
#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Verify totitle special cases!
-#endif /* __UCLIBC_MJN3_ONLY__ */
+# warning TODO: Verify totitle special cases!
+#endif
/* WARNING! These special cases work for glibc 2.2.4. Changes
* may be needed if the glibc locale tables are updated. */
- if ( (((__uwchar_t)(wc - 0x1c4)) <= (0x1cc - 0x1c4))
- || (wc == 0x1f1)
- ) {
+ if ((__uwchar_t)(wc - 0x1c4) <= (0x1cc - 0x1c4)
+ || wc == 0x1f1
+ ) {
++wc;
}
}
@@ -852,10 +766,9 @@ wint_t TOWCTRANS(wint_t wc, wctrans_t desc)
wint_t TOWCTRANS(wint_t wc, wctrans_t desc)
{
if (ENCODING == __ctype_encoding_7_bit) {
- if ((((__uwchar_t) wc) > 0x7f)
- || (((unsigned int)(desc - _CTYPE_tolower))
- > (_CTYPE_toupper - _CTYPE_tolower))
- ){
+ if ((__uwchar_t)wc > 0x7f
+ || (unsigned)(desc - _CTYPE_tolower) > (_CTYPE_toupper - _CTYPE_tolower)
+ ) {
/* We're in the C/POSIX locale, so ignore non-ASCII values
* as well an any mappings other than toupper or tolower. */
return wc;
@@ -864,19 +777,18 @@ wint_t TOWCTRANS(wint_t wc, wctrans_t desc)
if (desc == _CTYPE_tolower) {
return TOWLOWER(wc, __UCLIBC_CURLOCALE);
- } else if (((unsigned int)(desc - _CTYPE_toupper))
- <= (_CTYPE_totitle - _CTYPE_toupper)
- ) {
+ }
+ if ((unsigned)(desc - _CTYPE_toupper) <= (_CTYPE_totitle - _CTYPE_toupper)) {
wc = TOWUPPER(wc, __UCLIBC_CURLOCALE);
if (desc == _CTYPE_totitle) {
#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Verify totitle special cases!
-#endif /* __UCLIBC_MJN3_ONLY__ */
+# warning TODO: Verify totitle special cases!
+#endif
/* WARNING! These special cases work for glibc 2.2.4. Changes
* may be needed if the glibc locale tables are updated. */
- if ( (((__uwchar_t)(wc - 0x1c4)) <= (0x1cc - 0x1c4))
- || (wc == 0x1f1)
- ) {
+ if ((__uwchar_t)(wc - 0x1c4) <= (0x1cc - 0x1c4)
+ || wc == 0x1f1
+ ) {
++wc;
}
}
@@ -893,7 +805,7 @@ wint_t TOWCTRANS(wint_t wc, wctrans_t desc)
#ifdef L_towctrans_l
libc_hidden_def(towctrans_l)
-#endif /* L_towctrans_l */
+#endif
#endif /* __LOCALE_C_ONLY */
@@ -907,16 +819,15 @@ libc_hidden_def(towctrans)
static const char transstring[] = __CTYPE_TRANSTRING;
-libc_hidden_proto(wctrans)
wctrans_t wctrans(const char *property)
{
const unsigned char *p;
int i;
- p = transstring;
+ p = (const unsigned char *) transstring;
i = 1;
do {
- if (!strcmp(property, ++p)) {
+ if (!strcmp(property, (const char*) ++p)) {
return i;
}
++i;
@@ -932,11 +843,9 @@ libc_hidden_def(wctrans)
/**********************************************************************/
#ifdef L_wctrans_l
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning REMINDER: Currently wctrans_l simply calls wctrans.
-#endif /* __UCLIBC_MJN3_ONLY__ */
-
-libc_hidden_proto(wctrans)
+# ifdef __UCLIBC_MJN3_ONLY__
+# warning REMINDER: Currently wctrans_l simply calls wctrans.
+# endif
wctrans_t wctrans_l(const char *property, __locale_t locale)
{
diff --git a/libc/misc/wordexp/Makefile.in b/libc/misc/wordexp/Makefile.in
index 526807f25..3d642488b 100644
--- a/libc/misc/wordexp/Makefile.in
+++ b/libc/misc/wordexp/Makefile.in
@@ -1,21 +1,23 @@
# Makefile for uClibc
#
-# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := wordexp.c
+subdirs += libc/misc/wordexp
+
+CSRC-y := wordexp.c
MISC_WORDEXP_DIR := $(top_srcdir)libc/misc/wordexp
MISC_WORDEXP_OUT := $(top_builddir)libc/misc/wordexp
-MISC_WORDEXP_SRC := $(patsubst %.c,$(MISC_WORDEXP_DIR)/%.c,$(CSRC))
-MISC_WORDEXP_OBJ := $(patsubst %.c,$(MISC_WORDEXP_OUT)/%.o,$(CSRC))
+MISC_WORDEXP_SRC := $(patsubst %.c,$(MISC_WORDEXP_DIR)/%.c,$(CSRC-y))
+MISC_WORDEXP_OBJ := $(patsubst %.c,$(MISC_WORDEXP_OUT)/%.o,$(CSRC-y))
libc-$(UCLIBC_HAS_WORDEXP) += $(MISC_WORDEXP_OBJ)
-objclean-y += misc_wordexp_objclean
+objclean-y += CLEAN_libc/misc/wordexp
-misc_wordexp_objclean:
- $(RM) $(MISC_WORDEXP_OUT)/*.{o,os}
+CLEAN_libc/misc/wordexp:
+ $(do_rm) $(addprefix $(MISC_WORDEXP_OUT)/*., o os)
diff --git a/libc/misc/wordexp/wordexp.c b/libc/misc/wordexp/wordexp.c
index d8b2db16f..b1cc60942 100644
--- a/libc/misc/wordexp/wordexp.c
+++ b/libc/misc/wordexp/wordexp.c
@@ -16,10 +16,11 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ see <http://www.gnu.org/licenses/>. */
#include <features.h>
+#include <bits/kernel-features.h>
+#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
@@ -35,55 +36,19 @@
#include <glob.h>
#include <wordexp.h>
-/* Experimentally off - libc_hidden_proto(mempcpy) */
-/* Experimentally off - libc_hidden_proto(stpcpy) */
-/* Experimentally off - libc_hidden_proto(strchr) */
-/* Experimentally off - libc_hidden_proto(strcpy) */
-/* Experimentally off - libc_hidden_proto(strdup) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-/* Experimentally off - libc_hidden_proto(strndup) */
-/* Experimentally off - libc_hidden_proto(strspn) */
-/* Experimentally off - libc_hidden_proto(strcspn) */
-libc_hidden_proto(setenv)
-libc_hidden_proto(unsetenv)
-libc_hidden_proto(waitpid)
-libc_hidden_proto(kill)
-libc_hidden_proto(getuid)
-libc_hidden_proto(getpwnam_r)
-libc_hidden_proto(getpwuid_r)
-libc_hidden_proto(execve)
-libc_hidden_proto(dup2)
-libc_hidden_proto(atoi)
-libc_hidden_proto(fnmatch)
-libc_hidden_proto(pipe)
-libc_hidden_proto(fork)
-libc_hidden_proto(open)
-libc_hidden_proto(close)
-libc_hidden_proto(read)
-libc_hidden_proto(getenv)
-libc_hidden_proto(getpid)
-libc_hidden_proto(sprintf)
-libc_hidden_proto(fprintf)
-libc_hidden_proto(abort)
-libc_hidden_proto(glob)
-libc_hidden_proto(globfree)
-libc_hidden_proto(wordfree)
-#ifdef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_b_loc)
-#elif defined __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__ctype_b)
+#ifndef __ARCH_USE_MMU__
+# define fork vfork
#endif
#define __WORDEXP_FULL
-//#undef __WORDEXP_FULL
/*
* This is a recursive-descent-style word expansion routine.
*/
/* These variables are defined and initialized in the startup code. */
-//extern int __libc_argc;
-//extern char **__libc_argv;
+/*extern int __libc_argc;*/
+/*extern char **__libc_argv;*/
/* FIXME!!!! */
int attribute_hidden __libc_argc;
@@ -138,8 +103,9 @@ static __inline__ char *w_addchar(char *buffer, size_t * actlen,
return buffer;
}
-
+#ifndef MAX
#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
+#endif
static char *w_addmem(char *buffer, size_t * actlen, size_t * maxlen,
const char *str, size_t len)
{
@@ -373,8 +339,8 @@ parse_tilde(char **word, size_t * word_length, size_t * max_length,
static int
do_parse_glob(const char *glob_word, char **word, size_t * word_length,
- size_t * max_length, wordexp_t * pwordexp, const char *ifs,
- const char *ifs_white)
+ size_t * max_length, wordexp_t * pwordexp, const char *ifs
+ /*, const char *ifs_white*/)
{
int error;
int match;
@@ -497,7 +463,7 @@ parse_glob(char **word, size_t * word_length, size_t * max_length,
*word = w_newword(word_length, max_length);
for (i = 0; error == 0 && i < glob_list.we_wordc; i++)
error = do_parse_glob(glob_list.we_wordv[i], word, word_length,
- max_length, pwordexp, ifs, ifs_white);
+ max_length, pwordexp, ifs /*, ifs_white*/);
/* Now tidy up */
tidy_up:
@@ -787,6 +753,7 @@ parse_arith(char **word, size_t * word_length, size_t * max_length,
static void attribute_noreturn
exec_comm_child(char *comm, int *fildes, int showerr, int noexec)
{
+ int fd;
const char *args[4] = { _PATH_BSHELL, "-c", comm, NULL };
/* Execute the command, or just check syntax? */
@@ -794,16 +761,22 @@ exec_comm_child(char *comm, int *fildes, int showerr, int noexec)
args[1] = "-nc";
/* Redirect output. */
- dup2(fildes[1], 1);
- close(fildes[1]);
-
+ fd = fildes[1];
+ if (likely(fd != STDOUT_FILENO)) {
+ dup2(fd, STDOUT_FILENO);
+ close(fd);
+ }
+#if defined O_CLOEXEC && defined __UCLIBC_LINUX_SPECIFIC__ && defined __ASSUME_PIPE2
+ else {
+ /* Reset the close-on-exec flag (if necessary). */
+ fcntl (fd, F_SETFD, 0);
+ }
+#endif
/* Redirect stderr to /dev/null if we have to. */
if (showerr == 0) {
- int fd;
-
- close(2);
+ close(STDERR_FILENO);
fd = open(_PATH_DEVNULL, O_WRONLY);
- if (fd >= 0 && fd != 2) {
+ if (fd >= 0 && fd != STDERR_FILENO) {
dup2(fd, 2);
close(fd);
}
@@ -812,7 +785,8 @@ exec_comm_child(char *comm, int *fildes, int showerr, int noexec)
/* Make sure the subshell doesn't field-split on our behalf. */
unsetenv("IFS");
- close(fildes[0]);
+ if (fildes[0] != 1)
+ close(fildes[0]);
execve(_PATH_BSHELL, (char *const *) args, __environ);
/* Bad. What now? */
@@ -838,10 +812,15 @@ exec_comm(char *comm, char **word, size_t * word_length,
/* Don't fork() unless necessary */
if (!comm || !*comm)
return 0;
-
- if (pipe(fildes))
+#if defined O_CLOEXEC && defined __UCLIBC_LINUX_SPECIFIC__ && defined __ASSUME_PIPE2
+ if (pipe2(fildes, O_CLOEXEC) < 0)
/* Bad */
return WRDE_NOSPACE;
+#else
+ if (pipe(fildes) < 0)
+ /* Bad */
+ return WRDE_NOSPACE;
+#endif
if ((pid = fork()) < 0) {
/* Bad */
@@ -1481,28 +1460,28 @@ parse_param(char **word, size_t * word_length, size_t * max_length,
size_t exp_len;
size_t exp_maxl;
char *p;
- int quoted = 0; /* 1: single quotes; 2: double */
+ int quotes = 0; /* 1: single quotes; 2: double */
expanded = w_newword(&exp_len, &exp_maxl);
for (p = pattern; p && *p; p++) {
- size_t offset;
+ size_t _offset;
switch (*p) {
case '"':
- if (quoted == 2)
- quoted = 0;
- else if (quoted == 0)
- quoted = 2;
+ if (quotes == 2)
+ quotes = 0;
+ else if (quotes == 0)
+ quotes = 2;
else
break;
continue;
case '\'':
- if (quoted == 1)
- quoted = 0;
- else if (quoted == 0)
- quoted = 1;
+ if (quotes == 1)
+ quotes = 0;
+ else if (quotes == 0)
+ quotes = 1;
else
break;
@@ -1510,7 +1489,7 @@ parse_param(char **word, size_t * word_length, size_t * max_length,
case '*':
case '?':
- if (quoted) {
+ if (quotes) {
/* Convert quoted wildchar to escaped wildchar. */
expanded = w_addchar(expanded, &exp_len,
&exp_maxl, '\\');
@@ -1521,9 +1500,9 @@ parse_param(char **word, size_t * word_length, size_t * max_length,
break;
case '$':
- offset = 0;
+ _offset = 0;
error = parse_dollars(&expanded, &exp_len, &exp_maxl, p,
- &offset, flags, NULL, NULL, NULL, 1);
+ &_offset, flags, NULL, NULL, NULL, 1);
if (error) {
if (free_value)
free(value);
@@ -1533,16 +1512,16 @@ parse_param(char **word, size_t * word_length, size_t * max_length,
goto do_error;
}
- p += offset;
+ p += _offset;
continue;
case '~':
- if (quoted || exp_len)
+ if (quotes || exp_len)
break;
- offset = 0;
+ _offset = 0;
error = parse_tilde(&expanded, &exp_len, &exp_maxl, p,
- &offset, 0);
+ &_offset, 0);
if (error) {
if (free_value)
free(value);
@@ -1552,7 +1531,7 @@ parse_param(char **word, size_t * word_length, size_t * max_length,
goto do_error;
}
- p += offset;
+ p += _offset;
continue;
case '\\':