diff options
author | "Steven J. Hill" <sjhill@realitydiluted.com> | 2005-07-30 02:54:42 +0000 |
---|---|---|
committer | "Steven J. Hill" <sjhill@realitydiluted.com> | 2005-07-30 02:54:42 +0000 |
commit | 92ac94812b84cef7d9bddfffd0446721a7a6ee06 (patch) | |
tree | a5a2c895d613afb96fb71c9c19be9ec266db30d7 /libc | |
parent | ac02770c4a13eff9fef10c33ebb18d765f25a968 (diff) | |
download | uClibc-alpine-92ac94812b84cef7d9bddfffd0446721a7a6ee06.tar.bz2 uClibc-alpine-92ac94812b84cef7d9bddfffd0446721a7a6ee06.tar.xz |
Finalize the merge from the trunk. There are more files to be
merged, but they will be done manually.
Diffstat (limited to 'libc')
37 files changed, 725 insertions, 552 deletions
diff --git a/libc/inet/ntop.c b/libc/inet/ntop.c index bcdc57df8..35c302950 100644 --- a/libc/inet/ntop.c +++ b/libc/inet/ntop.c @@ -58,10 +58,12 @@ inet_ntop4(const u_char *src, char *dst, size_t size) i = 0; for (octet = 0; octet <= 3; octet++) { +#if 0 /* since src is unsigned char, it will never be > 255 ... */ if (src[octet] > 255) { __set_errno (ENOSPC); return (NULL); } +#endif tmp[i++] = '0' + src[octet] / 100; if (tmp[i - 1] == '0') { tmp[i - 1] = '0' + (src[octet] / 10 % 10); diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index f93d10952..35ab1d7a8 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -164,6 +164,12 @@ ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags) return (__socketcall(SYS_RECV, args)); } weak_alias(__libc_recv, recv); +#elif defined(__NR_recvfrom) +ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags) +{ + return (recvfrom(sockfd, buffer, len, flags, NULL, NULL)); +} +weak_alias(__libc_recv, recv); #endif #endif @@ -227,6 +233,12 @@ ssize_t __libc_send(int sockfd, const void *buffer, size_t len, int flags) return (__socketcall(SYS_SEND, args)); } weak_alias(__libc_send, send); +#elif defined(__NR_sendto) +ssize_t __libc_send(int sockfd, const void *buffer, size_t len, int flags) +{ + return (sendto(sockfd, buffer, len, flags, NULL, 0)); +} +weak_alias(__libc_send, send); #endif #endif diff --git a/libc/misc/error/err.c b/libc/misc/error/err.c index 5c53e545f..0d0637148 100644 --- a/libc/misc/error/err.c +++ b/libc/misc/error/err.c @@ -34,7 +34,7 @@ static void vwarn_work(const char *format, va_list args, int showerr) f = fmt + 11; /* At 11. */ if (showerr) { f -= 4; /* At 7. */ - _susv3_strerror_r(errno, buf, sizeof(buf)); + __xpg_strerror_r(errno, buf, sizeof(buf)); } __STDIO_AUTO_THREADLOCK(stderr); diff --git a/libc/misc/glob/glob.c b/libc/misc/glob/glob.c index 14e2a6e22..a93cf0ab4 100644 --- a/libc/misc/glob/glob.c +++ b/libc/misc/glob/glob.c @@ -59,7 +59,7 @@ int glob_pattern_p(const char *pattern, int quote) return 1; case '\\': - if (quote) + if (quote && p[1] != '\0') ++p; break; diff --git a/libc/misc/internals/Makefile b/libc/misc/internals/Makefile index 23816b38d..933b169a6 100644 --- a/libc/misc/internals/Makefile +++ b/libc/misc/internals/Makefile @@ -31,7 +31,7 @@ OBJS=$(COBJS) OBJ_LIST=../../obj.misc.internals -all: $(OBJ_LIST) interp.o +all: $(OBJ_LIST) interp.o static.o $(OBJ_LIST): $(OBJS) echo $(patsubst %, misc/internals/%, $(OBJS)) > $(OBJ_LIST) @@ -44,11 +44,7 @@ interp.c: Makefile "(\".interp\"))) =\""$(DYNAMIC_LINKER)"\";" >> interp.c echo "#endif" >> interp.c -interp.o: interp.c - $(CC) $(CFLAGS) -c $< -o $@ - $(STRIPTOOL) -x -R .note -R .comment $*.o - -$(COBJS): %.o : %.c +$(COBJS) interp.o static.o: %.o : %.c $(CC) $(CFLAGS) -c $< -o $@ $(STRIPTOOL) -x -R .note -R .comment $*.o diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index a33e6fe4a..21864ba4f 100644 --- a/libc/misc/internals/__uClibc_main.c +++ b/libc/misc/internals/__uClibc_main.c @@ -32,7 +32,7 @@ extern void __guard_setup(void); /* * Prototypes. */ -extern int main(int argc, char **argv, char **envp); +extern void *__libc_stack_end; extern void weak_function _stdio_init(void); extern int *weak_const_function __errno_location(void); extern int *weak_const_function __h_errno_location(void); @@ -165,14 +165,15 @@ void attribute_hidden (*__rtld_fini)(void) = NULL; * are initialized, just before we call the application's main function. */ void __attribute__ ((__noreturn__)) -__uClibc_start_main(int argc, char **argv, char **envp, - void (*app_init)(void), void (*app_fini)(void), void (*rtld_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) { #ifdef __ARCH_HAS_MMU__ unsigned long *aux_dat; Elf32_auxv_t auxvt[AT_EGID + 1]; #endif - + __libc_stack_end = stack_end; /* We need to initialize uClibc. If we are dynamically linked this * may have already been completed by the shared lib loader. We call * __uClibc_init() regardless, to be sure the right thing happens. */ @@ -180,15 +181,19 @@ __uClibc_start_main(int argc, char **argv, char **envp, __rtld_fini = rtld_fini; - /* If we are dynamically linked, then ldso already did this for us. */ - if (__environ==NULL) { - /* Statically linked. */ - __environ = envp; + /* The environment begins right after argv. */ + __environ = &argv[argc + 1]; + + /* If the first thing after argv is the arguments + * the the environment is empty. */ + if ((char *) __environ == *argv) { + /* Make __environ point to the NULL at argv[argc] */ + __environ = &argv[argc]; } /* Pull stuff from the ELF header when possible */ #ifdef __ARCH_HAS_MMU__ - aux_dat = (unsigned long*)envp; + aux_dat = (unsigned long*)__environ; while (*aux_dat) { aux_dat++; } @@ -247,23 +252,15 @@ __uClibc_start_main(int argc, char **argv, char **envp, /* * Finally, invoke application's main and then exit. */ - exit(main(argc, argv, envp)); + exit(main(argc, argv, __environ)); } - -/* __uClibc_main is the old main stub of the uClibc. This - * function is called from crt0 (uClibc 0.9.15 and older) after - * ALL shared libraries are initialized, and just before we call - * the application's main() function. - * - * Attention: This stub does not call the .init/.fini sections of - * the application. If you need this, please fix your uClibc port - * so that __uClibc_start_main is called by your crt0.S with - * _init and _fini properly set. -*/ +#ifdef _DL_FINI_CRT_COMPAT +extern int weak_function main(int argc, char **argv, char **envp); void __attribute__ ((__noreturn__)) -__uClibc_main(int argc, char **argv, char ** envp) +__uClibc_start_main(int argc, char **argv, char **envp, + void (*app_fini)(void), void (*app_init)(void)) { - __uClibc_start_main(argc, argv, envp, NULL, NULL, NULL); + __uClibc_main(main, argc, argv, app_init, app_fini, NULL, NULL); } - +#endif diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c index 90b4f5494..89c26110c 100644 --- a/libc/misc/pthread/weaks.c +++ b/libc/misc/pthread/weaks.c @@ -23,7 +23,6 @@ static int __pthread_return_0 __P ((void)); static int __pthread_return_1 __P ((void)); -static void __pthread_return_void __P ((void)); /**********************************************************************/ /* Weaks for application/library use. @@ -118,8 +117,3 @@ __pthread_return_1 (void) { return 1; } - -static void -__pthread_return_void (void) -{ -} diff --git a/libc/misc/sysvipc/ipc.h b/libc/misc/sysvipc/ipc.h index e1b94ad12..a5d443543 100644 --- a/libc/misc/sysvipc/ipc.h +++ b/libc/misc/sysvipc/ipc.h @@ -2,10 +2,10 @@ #define IPC_H #include <syscall.h> -#ifdef __NR_ipc - #define __IPC_64 0x100 +#ifdef __NR_ipc + /* The actual system call: all functions are multiplexed by this. */ extern int __syscall_ipc __P((int __call, int __first, int __second, int __third, void *__ptr)); diff --git a/libc/misc/sysvipc/msgq.c b/libc/misc/sysvipc/msgq.c index 411ea3ea4..758dbaa47 100644 --- a/libc/misc/sysvipc/msgq.c +++ b/libc/misc/sysvipc/msgq.c @@ -6,14 +6,18 @@ #ifdef L_msgctl #ifdef __NR_msgctl -_syscall3(int, msgctl, int, msqid, int, cmd | __IPC_64, struct msqid_ds *, buf); -#else +#define __NR___libc_msgctl __NR_msgctl +_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) +int msgctl(int msqid, int cmd, struct msqid_ds *buf) { - return __syscall_ipc(IPCOP_msgctl ,msqid ,cmd | __IPC_64 ,0 ,buf); -} +#ifdef __NR_msgctl + return __libc_msgctl(msqid, cmd | __IPC_64, buf); +#else + return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf); #endif +} #endif diff --git a/libc/misc/sysvipc/shm.c b/libc/misc/sysvipc/shm.c index d21d9f54b..29f3178d6 100644 --- a/libc/misc/sysvipc/shm.c +++ b/libc/misc/sysvipc/shm.c @@ -48,13 +48,17 @@ void * shmat (int shmid, const void *shmaddr, int shmflg) #ifdef L_shmctl /* Provide operations to control over shared memory segments. */ #ifdef __NR_shmctl -_syscall3(int, shmctl, int, shmid, int, cmd | __IPC_64, struct shmid_ds *, buf); -#else -int shmctl (int shmid, int cmd, struct shmid_ds *buf) +#define __NR___libc_shmctl __NR_shmctl +_syscall3(int, __libc_shmctl, int, shmid, int, cmd, struct shmid_ds *, buf); +#endif +int shmctl(int shmid, int cmd, struct shmid_ds *buf) { - return __syscall_ipc(IPCOP_shmctl, shmid, cmd | __IPC_64 , 0, buf); -} +#ifdef __NR_shmctl + return __libc_shmctl(shmid, cmd | __IPC_64, buf); +#else + return __syscall_ipc(IPCOP_shmctl, shmid, cmd | __IPC_64, 0, buf); #endif +} #endif diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c index 7b1ae388b..f43bb8a3c 100644 --- a/libc/misc/time/time.c +++ b/libc/misc/time/time.c @@ -118,6 +118,15 @@ * Make lookup_tzname() static (as it should have been). * Have strftime() get timezone information from the passed struct * for the %z and %Z conversions when using struct tm extensions. + * + * Jul 24, 2004 + * Fix 2 bugs in strftime related to glibc struct tm extensions. + * 1) Need to negate tm_gmtoff field value when used. (bug 336). + * 2) Deal with NULL ptr case for tm_zone field, which was causing + * segfaults in both the NIST/PCTS tests and the Python 2.4.1 + * self-test suite. + * NOTE: We set uninitialized timezone names to "???", and this + * differs (intentionally) from glibc's behavior. */ #define _GNU_SOURCE @@ -1066,7 +1075,7 @@ size_t __XL(strftime)(char *__restrict s, size_t maxsize, #define RSP_TZUNLOCK ((void) 0) #define RSP_TZNAME timeptr->tm_zone -#define RSP_GMT_OFFSET timeptr->tm_gmtoff +#define RSP_GMT_OFFSET (-timeptr->tm_gmtoff) #else @@ -1084,6 +1093,20 @@ size_t __XL(strftime)(char *__restrict s, size_t maxsize, if (*p == 'Z') { o = 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 + * handle NULL, which looks to be all that glibc does. + * At least that catches the memset() with 0 case. + * NOTE: We handle this case differently than glibc! + * It uses system timezone name (based on tm_isdst) in this + * 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 = "???"; + } +#endif assert(o != NULL); #if 0 if (!o) { /* PARANOIA */ @@ -1939,7 +1962,9 @@ void tzset(void) daylight = !!_time_tzinfo[1].tzname[0]; timezone = _time_tzinfo[0].gmt_offset; +#if defined(__UCLIBC_HAS_TZ_FILE__) FAST_DONE: +#endif TZUNLOCK; } diff --git a/libc/stdio/_fpmaxtostr.c b/libc/stdio/_fpmaxtostr.c index 7fd67ffb4..b9aacdca8 100644 --- a/libc/stdio/_fpmaxtostr.c +++ b/libc/stdio/_fpmaxtostr.c @@ -11,8 +11,8 @@ #include <locale.h> #include <bits/uClibc_fpmax.h> -typedef void (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, - intptr_t buf); +typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, + intptr_t buf); /* Copyright (C) 2000, 2001, 2003 Manuel Novoa III @@ -198,14 +198,13 @@ static const __fpmax_t exp16_table[] = { #define FPO_STR_WIDTH (0x80 | ' '); #define FPO_STR_PREC 'p' -size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, - __fp_outfunc_t fp_outfunc) +ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, + __fp_outfunc_t fp_outfunc) { #ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ __fpmax_t lower_bnd; __fpmax_t upper_bnd = 1e9; #endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */ - uint_fast32_t digit_block; #ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ uint_fast32_t base = 10; const __fpmax_t *power_table; @@ -221,9 +220,8 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, int nblk2; /* This does not need to be initialized. */ const char *ts; /* This does not need to be initialized. */ #endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */ - int i, j; int round, o_exp; - int exp, exp_neg; + int exp; int width, preci; int cnt; char *s; @@ -304,34 +302,36 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, goto EXIT_SPECIAL; } + { + int i, j; #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Clean up defines when hexadecimal float notation is unsupported. #endif /* __UCLIBC_MJN3_ONLY__ */ #ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ - if ((mode|0x20) == 'a') { - lower_bnd = 0x1.0p31L; - upper_bnd = 0x1.0p32L; - power_table = exp16_table; - exp = HEX_DIGITS_PER_BLOCK - 1; - i = EXP16_TABLE_SIZE; - j = EXP16_TABLE_MAX; - dpb = HEX_DIGITS_PER_BLOCK; - ndb = NUM_HEX_DIGIT_BLOCKS; - nd = NUM_HEX_DIGITS; - base = 16; - } else { - lower_bnd = 1e8; -/* upper_bnd = 1e9; */ - power_table = exp10_table; - exp = DIGITS_PER_BLOCK - 1; - i = EXP10_TABLE_SIZE; - j = EXP10_TABLE_MAX; -/* dpb = DIGITS_PER_BLOCK; */ -/* ndb = NUM_DIGIT_BLOCKS; */ -/* base = 10; */ - } + if ((mode|0x20) == 'a') { + lower_bnd = 0x1.0p31L; + upper_bnd = 0x1.0p32L; + power_table = exp16_table; + exp = HEX_DIGITS_PER_BLOCK - 1; + i = EXP16_TABLE_SIZE; + j = EXP16_TABLE_MAX; + dpb = HEX_DIGITS_PER_BLOCK; + ndb = NUM_HEX_DIGIT_BLOCKS; + nd = NUM_HEX_DIGITS; + base = 16; + } else { + lower_bnd = 1e8; + /* upper_bnd = 1e9; */ + power_table = exp10_table; + exp = DIGITS_PER_BLOCK - 1; + i = EXP10_TABLE_SIZE; + j = EXP10_TABLE_MAX; + /* dpb = DIGITS_PER_BLOCK; */ + /* ndb = NUM_DIGIT_BLOCKS; */ + /* base = 10; */ + } @@ -345,32 +345,35 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, #define ndb NUM_DIGIT_BLOCKS #define nd DECIMAL_DIG - exp = DIGITS_PER_BLOCK - 1; - i = EXP10_TABLE_SIZE; - j = EXP10_TABLE_MAX; + exp = DIGITS_PER_BLOCK - 1; + i = EXP10_TABLE_SIZE; + j = EXP10_TABLE_MAX; #endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */ - exp_neg = 0; - if (x < lower_bnd) { /* Do we need to scale up or down? */ - exp_neg = 1; - } - - do { - --i; - if (exp_neg) { - if (x * power_table[i] < upper_bnd) { - x *= power_table[i]; - exp -= j; - } - } else { - if (x / power_table[i] >= lower_bnd) { - x /= power_table[i]; - exp += j; + { + int exp_neg = 0; + if (x < lower_bnd) { /* Do we need to scale up or down? */ + exp_neg = 1; } + + do { + --i; + if (exp_neg) { + if (x * power_table[i] < upper_bnd) { + x *= power_table[i]; + exp -= j; + } + } else { + if (x / power_table[i] >= lower_bnd) { + x /= power_table[i]; + exp += j; + } + } + j >>= 1; + } while (i); } - j >>= 1; - } while (i); + } if (x >= upper_bnd) { /* Handle bad rounding case. */ x /= power_table[0]; ++exp; @@ -378,22 +381,25 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, assert(x < upper_bnd); GENERATE_DIGITS: - s = buf + 2; /* Leave space for '\0' and '0'. */ - i = 0; - do { - digit_block = (uint_fast32_t) x; - assert(digit_block < upper_bnd); + { + int i, j; + s = buf + 2; /* Leave space for '\0' and '0'. */ + i = 0; + do { + uint_fast32_t digit_block = (uint_fast32_t) x; + assert(digit_block < upper_bnd); #ifdef __UCLIBC_MJN3_ONLY__ #warning CONSIDER: Can rounding be a problem? #endif /* __UCLIBC_MJN3_ONLY__ */ - x = (x - digit_block) * upper_bnd; - s += dpb; - j = 0; - do { - s[- ++j] = '0' + (digit_block % base); - digit_block /= base; - } while (j < dpb); - } while (++i < ndb); + x = (x - digit_block) * upper_bnd; + s += dpb; + j = 0; + do { + s[- ++j] = '0' + (digit_block % base); + digit_block /= base; + } while (j < dpb); + } while (++i < ndb); + } /*************************************************************************/ @@ -421,18 +427,21 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, *s++ = 0; /* Terminator for rounding and 0-triming. */ *s = '0'; /* Space to round. */ - i = 0; - e = s + nd + 1; - if (round < nd) { - e = s + round + 2; - if (*e >= '0' + (base/2)) { /* NOTE: We always round away from 0! */ - i = 1; + { + int i; + i = 0; + e = s + nd + 1; + if (round < nd) { + e = s + round + 2; + if (*e >= '0' + (base/2)) { /* NOTE: We always round away from 0! */ + i = 1; + } } - } - do { /* Handle rounding and trim trailing 0s. */ - *--e += i; /* Add the carry. */ - } while ((*e == '0') || (*e > '0' - 1 + base)); + do { /* Handle rounding and trim trailing 0s. */ + *--e += i; /* Add the carry. */ + } while ((*e == '0') || (*e > '0' - 1 + base)); + } #ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ if ((mode|0x20) == 'a') { @@ -480,80 +489,81 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, sign_str[5] = 0; ppc = pc_fwi + 6; - i = e - s; /* Total digits is 'i'. */ - if (o_exp >= 0) { + { + int i = e - s; /* Total digits is 'i'. */ + if (o_exp >= 0) { #ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ - const char *p; + const char *p; - if (PRINT_INFO_FLAG_VAL(info,group) - && *(p = __UCLIBC_CURLOCALE_DATA.grouping) - ) { - int nblk1; + if (PRINT_INFO_FLAG_VAL(info,group) + && *(p = __UCLIBC_CURLOCALE_DATA.grouping) + ) { + int nblk1; - nblk2 = nblk1 = *p; - if (*++p) { - nblk2 = *p; - assert(!*++p); - } + nblk2 = nblk1 = *p; + if (*++p) { + nblk2 = *p; + assert(!*++p); + } - if (o_exp >= nblk1) { - num_groups = (o_exp - nblk1) / nblk2 + 1; - initial_group = (o_exp - nblk1) % nblk2; + if (o_exp >= nblk1) { + num_groups = (o_exp - nblk1) / nblk2 + 1; + initial_group = (o_exp - nblk1) % nblk2; #ifdef __UCLIBC_HAS_WCHAR__ - if (PRINT_INFO_FLAG_VAL(info,wide)) { - /* _fp_out_wide() will fix this up. */ - ts = fmt + THOUSEP_OFFSET; - tslen = 1; - } else { + if (PRINT_INFO_FLAG_VAL(info,wide)) { + /* _fp_out_wide() will fix this up. */ + ts = fmt + THOUSEP_OFFSET; + tslen = 1; + } else { #endif /* __UCLIBC_HAS_WCHAR__ */ - ts = __UCLIBC_CURLOCALE_DATA.thousands_sep; - tslen = __UCLIBC_CURLOCALE_DATA.thousands_sep_len; + ts = __UCLIBC_CURLOCALE_DATA.thousands_sep; + tslen = __UCLIBC_CURLOCALE_DATA.thousands_sep_len; #ifdef __UCLIBC_HAS_WCHAR__ - } + } #endif /* __UCLIBC_HAS_WCHAR__ */ - width -= num_groups * tslen; + width -= num_groups * tslen; + } } - } #endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */ - ppc[0] = FPO_STR_PREC; - ppc[2] = (intptr_t)(s); - if (o_exp >= i) { /* all digit(s) left of decimal */ - ppc[1] = i; - ppc += 3; - o_exp -= i; - i = 0; - if (o_exp>0) { /* have 0s left of decimal */ - ppc[0] = FPO_ZERO_PAD; + ppc[0] = FPO_STR_PREC; + ppc[2] = (intptr_t)(s); + if (o_exp >= i) { /* all digit(s) left of decimal */ + ppc[1] = i; + ppc += 3; + o_exp -= i; + i = 0; + if (o_exp>0) { /* have 0s left of decimal */ + ppc[0] = FPO_ZERO_PAD; + ppc[1] = o_exp; + ppc[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET); + ppc += 3; + } + } else if (o_exp > 0) { /* decimal between digits */ ppc[1] = o_exp; - ppc[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET); ppc += 3; + s += o_exp; + i -= o_exp; } - } else if (o_exp > 0) { /* decimal between digits */ - ppc[1] = o_exp; - ppc += 3; - s += o_exp; - i -= o_exp; + o_exp = -1; } - o_exp = -1; - } - if (PRINT_INFO_FLAG_VAL(info,alt) - || (i) - || ((o_mode != 'g') + if (PRINT_INFO_FLAG_VAL(info,alt) + || (i) + || ((o_mode != 'g') #ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ - && (o_mode != 'a') + && (o_mode != 'a') #endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */ - && (preci > 0)) - ) { - ppc[0] = FPO_STR_PREC; + && (preci > 0)) + ) { + ppc[0] = FPO_STR_PREC; #ifdef __LOCALE_C_ONLY - ppc[1] = 1; - ppc[2] = (intptr_t)(fmt + DECPT_OFFSET); + ppc[1] = 1; + ppc[2] = (intptr_t)(fmt + DECPT_OFFSET); #else /* __LOCALE_C_ONLY */ #ifdef __UCLIBC_HAS_WCHAR__ if (PRINT_INFO_FLAG_VAL(info,wide)) { @@ -569,39 +579,41 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, #endif /* __UCLIBC_HAS_WCHAR__ */ #endif /* __LOCALE_C_ONLY */ ppc += 3; - } - - if (++o_exp < 0) { /* Have 0s right of decimal. */ - ppc[0] = FPO_ZERO_PAD; - ppc[1] = -o_exp; - ppc[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET); - ppc += 3; - } - if (i) { /* Have digit(s) right of decimal. */ - ppc[0] = FPO_STR_PREC; - ppc[1] = i; - ppc[2] = (intptr_t)(s); - ppc += 3; - } + } - if (((o_mode != 'g') || PRINT_INFO_FLAG_VAL(info,alt)) -#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ - && !sufficient_precision -#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */ - ) { - i -= o_exp; - if (i < preci) { /* Have 0s right of digits. */ - i = preci - i; + if (++o_exp < 0) { /* Have 0s right of decimal. */ ppc[0] = FPO_ZERO_PAD; - ppc[1] = i; + ppc[1] = -o_exp; ppc[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET); ppc += 3; } + if (i) { /* Have digit(s) right of decimal. */ + ppc[0] = FPO_STR_PREC; + ppc[1] = i; + ppc[2] = (intptr_t)(s); + ppc += 3; + } + + if (((o_mode != 'g') || PRINT_INFO_FLAG_VAL(info,alt)) +#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ + && !sufficient_precision +#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */ + ) { + i -= o_exp; + if (i < preci) { /* Have 0s right of digits. */ + i = preci - i; + ppc[0] = FPO_ZERO_PAD; + ppc[1] = i; + ppc[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET); + ppc += 3; + } + } } /* Build exponent string. */ if (mode != 'f') { char *p = exp_buf + sizeof(exp_buf); + int j; char exp_char = *exp_buf; char exp_sign = '+'; #ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ @@ -631,43 +643,46 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, } EXIT_SPECIAL: - ppc_last = ppc; - ppc = pc_fwi + 4; /* Need width fields starting with second. */ - do { - width -= *ppc; - ppc += 3; - } while (ppc < ppc_last); + { + int i; + ppc_last = ppc; + ppc = pc_fwi + 4; /* Need width fields starting with second. */ + do { + width -= *ppc; + ppc += 3; + } while (ppc < ppc_last); - ppc = pc_fwi; - ppc[0] = FPO_STR_WIDTH; - ppc[1] = i = ((*sign_str) != 0); - ppc[2] = (intptr_t) sign_str; + ppc = pc_fwi; + ppc[0] = FPO_STR_WIDTH; + ppc[1] = i = ((*sign_str) != 0); + ppc[2] = (intptr_t) sign_str; #ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ - if (((mode|0x20) == 'a') && (pc_fwi[3] >= 16)) { /* Hex sign handling. */ - /* Hex and not inf or nan, so prefix with 0x. */ - char *h = sign_str + i; - *h = '0'; - *++h = 'x' - 'p' + *exp_buf; - *++h = 0; - ppc[1] = (i += 2); - } + if (((mode|0x20) == 'a') && (pc_fwi[3] >= 16)) { /* Hex sign handling. */ + /* Hex and not inf or nan, so prefix with 0x. */ + char *h = sign_str + i; + *h = '0'; + *++h = 'x' - 'p' + *exp_buf; + *++h = 0; + ppc[1] = (i += 2); + } #endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */ - if ((width -= i) > 0) { - if (PRINT_INFO_FLAG_VAL(info,left)) { /* Left-justified. */ - ppc_last[0] = FPO_STR_WIDTH; - ppc_last[1] = width; - ppc_last[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET); - ppc_last += 3; - } else if (info->pad == '0') { /* 0 padding */ - ppc[4] += width; /* Pad second field. */ - } else { - ppc[1] += width; /* Pad first (sign) field. */ + if ((width -= i) > 0) { + if (PRINT_INFO_FLAG_VAL(info,left)) { /* Left-justified. */ + ppc_last[0] = FPO_STR_WIDTH; + ppc_last[1] = width; + ppc_last[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET); + ppc_last += 3; + } else if (info->pad == '0') { /* 0 padding */ + ppc[4] += width; /* Pad second field. */ + } else { + ppc[1] += width; /* Pad first (sign) field. */ + } } - } - cnt = 0; + cnt = 0; + } do { #ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ @@ -685,7 +700,9 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, blk = nblk2; } else if (len >= blk) { /* Enough digits for a group. */ /* printf("norm: len=%d blk=%d \"%.*s\"\n", len, blk, blk, gp); */ - fp_outfunc(fp, *ppc, blk, (intptr_t) gp); + if (fp_outfunc(fp, *ppc, blk, (intptr_t) gp) != blk) { + return -1; + } assert(gp); if (*gp) { gp += blk; @@ -695,7 +712,9 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, /* printf("trans: len=%d blk=%d \"%.*s\"\n", len, blk, len, gp); */ if (len) { /* printf("len\n"); */ - fp_outfunc(fp, *ppc, len, (intptr_t) gp); + if (fp_outfunc(fp, *ppc, len, (intptr_t) gp) != len) { + return -1; + } gp += len; } @@ -718,7 +737,9 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, } --num_groups; - fp_outfunc(fp, FPO_STR_PREC, tslen, (intptr_t) ts); + if (fp_outfunc(fp, FPO_STR_PREC, tslen, (intptr_t) ts) != tslen) { + return -1; + } blk = nblk2; /* printf("num_groups=%d blk=%d\n", num_groups, blk); */ @@ -727,8 +748,11 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, } else #endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */ - - fp_outfunc(fp, *ppc, ppc[1], ppc[2]); /* NOTE: Remember 'else' above! */ + { /* NOTE: Remember 'else' above! */ + if (fp_outfunc(fp, *ppc, ppc[1], ppc[2]) != ppc[1]) { + return -1; + } + } cnt += ppc[1]; ppc += 3; diff --git a/libc/stdio/old_vfprintf.c b/libc/stdio/old_vfprintf.c index 1b7af96f9..23cb10f94 100644 --- a/libc/stdio/old_vfprintf.c +++ b/libc/stdio/old_vfprintf.c @@ -448,7 +448,7 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt, if (*fmt == 'm') { flag[FLAG_PLUS] = '\0'; flag[FLAG_0_PAD] = ' '; - p = _glibc_strerror_r(errno, tmp, sizeof(tmp)); + p = __glibc_strerror_r(errno, tmp, sizeof(tmp)); goto print; } #endif diff --git a/libc/stdio/perror.c b/libc/stdio/perror.c index 83db7689f..26a0cebd9 100644 --- a/libc/stdio/perror.c +++ b/libc/stdio/perror.c @@ -30,7 +30,7 @@ void perror(register const char *s) { char buf[64]; fprintf(stderr, "%s%s%s\n", s, sep, - _glibc_strerror_r(errno, buf, sizeof(buf))); + __glibc_strerror_r(errno, buf, sizeof(buf))); } #endif } diff --git a/libc/stdio/vfprintf.c b/libc/stdio/vfprintf.c index d3214fff0..10114f061 100644 --- a/libc/stdio/vfprintf.c +++ b/libc/stdio/vfprintf.c @@ -410,11 +410,11 @@ typedef struct { only returns -1 if sets error indicator for the stream. */ #ifdef __STDIO_PRINTF_FLOAT -typedef void (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, - intptr_t buf); +typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, + intptr_t buf); -extern size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, - __fp_outfunc_t fp_outfunc); +extern ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, + __fp_outfunc_t fp_outfunc); #endif extern int _ppfs_init(ppfs_t *ppfs, const char *fmt0); /* validates */ @@ -1185,7 +1185,7 @@ int register_printf_function(int spec, printf_function handler, * In other words, we don't currently support glibc's 'I' flag. * We do accept it, but it is currently ignored. */ -static void _charpad(FILE * __restrict stream, int padchar, size_t numpad); +static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad); #ifdef L_vfprintf @@ -1201,16 +1201,20 @@ static void _charpad(FILE * __restrict stream, int padchar, size_t numpad); #ifdef __STDIO_PRINTF_FLOAT -static void _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) +static size_t _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) { + size_t r = 0; + if (type & 0x80) { /* Some type of padding needed. */ int buflen = strlen((const char *) buf); if ((len -= buflen) > 0) { - _charpad(fp, (type & 0x7f), len); + if ((r = _charpad(fp, (type & 0x7f), len)) != len) { + return r; + } } len = buflen; } - OUTNSTR(fp, (const char *) buf, len); + return r + OUTNSTR(fp, (const char *) buf, len); } #endif /* __STDIO_PRINTF_FLOAT */ @@ -1226,12 +1230,12 @@ static void _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) #define _outnwcs(stream, wstring, len) _wstdio_fwrite(wstring, len, stream) #define FP_OUT _fp_out_wide -static void _outnstr(FILE *stream, const char *s, size_t wclen) +static size_t _outnstr(FILE *stream, const char *s, size_t wclen) { /* NOTE!!! len here is the number of wchars we want to generate!!! */ wchar_t wbuf[64]; mbstate_t mbstate; - size_t todo, r; + size_t todo, r, n; mbstate.__mask = 0; todo = wclen; @@ -1243,9 +1247,14 @@ static void _outnstr(FILE *stream, const char *s, size_t wclen) : sizeof(wbuf)/sizeof(wbuf[0])), &mbstate); assert(((ssize_t)r) > 0); - _outnwcs(stream, wbuf, r); - todo -= r; + n = _outnwcs(stream, wbuf, r); + todo -= n; + if (n != r) { + break; + } } + + return wclen - todo; } #ifdef __STDIO_PRINTF_FLOAT @@ -1259,16 +1268,19 @@ static void _outnstr(FILE *stream, const char *s, size_t wclen) #define NUM_DIGIT_BLOCKS ((DECIMAL_DIG+DIGITS_PER_BLOCK-1)/DIGITS_PER_BLOCK) #define BUF_SIZE ( 3 + NUM_DIGIT_BLOCKS * DIGITS_PER_BLOCK ) -static void _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) +static size_t _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) { wchar_t wbuf[BUF_SIZE]; const char *s = (const char *) buf; + size_t r = 0; int i; if (type & 0x80) { /* Some type of padding needed */ int buflen = strlen(s); if ((len -= buflen) > 0) { - _charpad(fp, (type & 0x7f), len); + if ((r = _charpad(fp, (type & 0x7f), len)) != len) { + return r; + } } len = buflen; } @@ -1294,8 +1306,10 @@ static void _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) } while (++i < len); - OUTNSTR(fp, wbuf, len); + r += OUTNSTR(fp, wbuf, len); } + + return r; } #endif /* __STDIO_PRINTF_FLOAT */ @@ -1385,16 +1399,19 @@ static int _ppwfs_init(register ppfs_t *ppfs, const wchar_t *fmt0) #endif /* L_vfprintf */ -static void _charpad(FILE * __restrict stream, int padchar, size_t numpad) +static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad) { + size_t todo = numpad; + /* TODO -- Use a buffer to cut down on function calls... */ FMT_TYPE pad[1]; *pad = padchar; - while (numpad) { - OUTNSTR(stream, pad, 1); - --numpad; + while (todo && (OUTNSTR(stream, pad, 1) == 1)) { + --todo; } + + return numpad - todo; } /* TODO -- Dynamically allocate work space to accomodate stack-poor archs? */ @@ -1583,13 +1600,18 @@ static int _do_one_spec(FILE * __restrict stream, numfill = ((numfill > SLEN) ? numfill - SLEN : 0); } else if (ppfs->conv_num <= CONV_A) { /* floating point */ #ifdef __STDIO_PRINTF_FLOAT - *count += - _fpmaxtostr(stream, - (__fpmax_t) - (PRINT_INFO_FLAG_VAL(&(ppfs->info),is_long_double) - ? *(long double *) *argptr - : (long double) (* (double *) *argptr)), - &ppfs->info, FP_OUT ); + ssize_t nf; + nf = _fpmaxtostr(stream, + (__fpmax_t) + (PRINT_INFO_FLAG_VAL(&(ppfs->info),is_long_double) + ? *(long double *) *argptr + : (long double) (* (double *) *argptr)), + &ppfs->info, FP_OUT ); + if (nf < 0) { + return -1; + } + *count += nf; + return 0; #else /* __STDIO_PRINTF_FLOAT */ return -1; /* TODO -- try to continue? */ @@ -1708,7 +1730,7 @@ static int _do_one_spec(FILE * __restrict stream, #ifdef __UCLIBC_HAS_PRINTF_M_SPEC__ } else if (ppfs->conv_num == CONV_m) { - s = _glibc_strerror_r(errno, buf, sizeof(buf)); + s = __glibc_strerror_r(errno, buf, sizeof(buf)); goto SET_STRING_LEN; #endif } else { @@ -1757,18 +1779,24 @@ static int _do_one_spec(FILE * __restrict stream, /* Now handle the output itself. */ if (!PRINT_INFO_FLAG_VAL(&(ppfs->info),left)) { - _charpad(stream, ' ', numpad); + if (_charpad(stream, ' ', numpad) != numpad) { + return -1; + } numpad = 0; } OUTPUT(stream, prefix + prefix_num); - _charpad(stream, '0', numfill); + if (_charpad(stream, '0', numfill) != numfill) { + return -1; + } #ifdef L_vfprintf #ifdef __UCLIBC_HAS_WCHAR__ if (!ws) { assert(s); - _outnstr(stream, s, slen); + if (_outnstr(stream, s, slen) != slen) { + return -1; + } } else { /* wide string */ size_t t; mbstate.__mask = 0; /* Initialize the mbstate. */ @@ -1776,25 +1804,35 @@ static int _do_one_spec(FILE * __restrict stream, t = (slen <= sizeof(buf)) ? slen : sizeof(buf); t = wcsrtombs(buf, &ws, t, &mbstate); assert (t != ((size_t)(-1))); - _outnstr(stream, buf, t); + if (_outnstr(stream, buf, t) != t) { + return -1; + } slen -= t; } } #else /* __UCLIBC_HAS_WCHAR__ */ - _outnstr(stream, s, slen); + if (_outnstr(stream, s, slen) != slen) { + return -1; + } #endif /* __UCLIBC_HAS_WCHAR__ */ #else /* L_vfprintf */ if (!ws) { assert(s); - _outnstr(stream, s, SLEN); + if (_outnstr(stream, s, SLEN) != SLEN) { + return -1; + } } else { - _outnwcs(stream, ws, SLEN); + if (_outnwcs(stream, ws, SLEN) != SLEN) { + return -1; + } } #endif /* L_vfprintf */ - _charpad(stream, ' ', numpad); + if (_charpad(stream, ' ', numpad) != numpad) { + return -1; + } } return 0; @@ -1840,7 +1878,7 @@ int VFPRINTF (FILE * __restrict stream, } if (format-s) { /* output any literal text in format string */ - if ( (r = OUTNSTR(stream, s, format-s)) < 0) { + if ( (r = OUTNSTR(stream, s, format-s)) != (format-s)) { count = -1; break; } diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c index e34c86778..77c2cdc69 100644 --- a/libc/stdlib/abort.c +++ b/libc/stdlib/abort.c @@ -30,99 +30,120 @@ Cambridge, MA 02139, USA. */ /* Our last ditch effort to commit suicide */ -#if defined(__i386__) +#if defined(__alpha__) +#define ABORT_INSTRUCTION asm ("call_pal 0") +#elif defined(__hppa__) +#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%r0)") +#elif defined(__i386__) #define ABORT_INSTRUCTION asm ("hlt") #elif defined(__ia64__) #define ABORT_INSTRUCTION asm ("break 0") +#elif defined(__m68k__) +#define ABORT_INSTRUCTION asm ("illegal") #elif defined(__mc68000__) #define ABORT_INSTRUCTION asm (".long 0xffffffff") #elif defined(__mips__) #define ABORT_INSTRUCTION asm ("break 255") +#elif defined(__powerpc__) +#define ABORT_INSTRUCTION asm (".long 0") #elif defined(__s390__) #define ABORT_INSTRUCTION asm (".word 0") #elif defined(__sparc__) #define ABORT_INSTRUCTION asm ("unimp 0xf00") -#elif defined(__x86_64__) -#define ABORT_INSTRUCTION asm ("hlt") -#elif defined(__hppa__) -#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%r0)") -#elif defined(__powerpc__) -#define ABORT_INSTRUCTION asm (".long 0") #elif defined(__SH5__) #define ABORT_INSTRUCTION asm ("movi 0x10, r9; shori 0xff, r9; trapa r9") #elif defined(__sh2__) #define ABORT_INSTRUCTION asm ("trapa #32") #elif defined(__sh__) #define ABORT_INSTRUCTION asm ("trapa #0xff") +#elif defined(__x86_64__) +#define ABORT_INSTRUCTION asm ("hlt") #else #define ABORT_INSTRUCTION +#warning no abort instruction define for your arch #endif +#ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__ +extern void weak_function _stdio_term(void); +#endif extern void _exit __P((int __status)) __attribute__ ((__noreturn__)); static int been_there_done_that = 0; -/* Be prepared in case multiple threads try to abort(). */ +/* Be prepared in case multiple threads try to abort() */ #ifdef __UCLIBC_HAS_THREADS__ -#include <pthread.h> +# include <pthread.h> static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; # define LOCK __pthread_mutex_lock(&mylock) -# define UNLOCK __pthread_mutex_unlock(&mylock); +# define UNLOCK __pthread_mutex_unlock(&mylock) #else # define LOCK # define UNLOCK #endif -/* Cause an abnormal program termination with core-dump. */ +/* Cause an abnormal program termination with core-dump */ void abort(void) { - sigset_t sigset; - - /* Make sure we acquire the lock before proceeding. */ - LOCK; - - /* Unmask SIGABRT to be sure we can get it */ - if (__sigemptyset(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) { - sigprocmask(SIG_UNBLOCK, &sigset, (sigset_t *) NULL); - } - - while (1) { - /* Try to suicide with a SIGABRT. */ - if (been_there_done_that == 0) { - been_there_done_that++; - UNLOCK; - raise(SIGABRT); - LOCK; - } + sigset_t sigset; - /* Still here? Try to remove any signal handlers. */ - if (been_there_done_that == 1) { - struct sigaction act; + /* Make sure we acquire the lock before proceeding */ + LOCK; - been_there_done_that++; - memset (&act, '\0', sizeof (struct sigaction)); - act.sa_handler = SIG_DFL; - __sigfillset (&act.sa_mask); - act.sa_flags = 0; - sigaction (SIGABRT, &act, NULL); + /* Unmask SIGABRT to be sure we can get it */ + if (__sigemptyset(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) { + sigprocmask(SIG_UNBLOCK, &sigset, (sigset_t *) NULL); } - /* Still here? Try to suicide with an illegal instruction */ - if (been_there_done_that == 2) { - been_there_done_that++; - ABORT_INSTRUCTION; - } + while (1) { + /* Try to suicide with a SIGABRT */ + if (been_there_done_that == 0) { + been_there_done_that++; + +#ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__ + /* If we are using stdio, try to shut it down. At the very least, + * this will attemt to commit all buffered writes. It may also + * unboffer all writable files, or close them outright. + * Check the stdio routines for details. */ + if (_stdio_term) { + _stdio_term(); + } +#endif - /* Still here? Try to at least exit */ - if (been_there_done_that == 3) { - been_there_done_that++; - _exit (127); +abort_it: + UNLOCK; + raise(SIGABRT); + LOCK; + } + + /* Still here? Try to remove any signal handlers */ + if (been_there_done_that == 1) { + struct sigaction act; + + been_there_done_that++; + memset(&act, '\0', sizeof(struct sigaction)); + act.sa_handler = SIG_DFL; + __sigfillset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGABRT, &act, NULL); + + goto abort_it; + } + + /* Still here? Try to suicide with an illegal instruction */ + if (been_there_done_that == 2) { + been_there_done_that++; + ABORT_INSTRUCTION; + } + + /* Still here? Try to at least exit */ + if (been_there_done_that == 3) { + been_there_done_that++; + _exit(127); + } + + /* Still here? We're screwed. Sleepy time. Good night. */ + while (1) + /* Try for ever and ever */ + ABORT_INSTRUCTION; } - - /* Still here? We're screwed. Sleepy time. Good night */ - while (1) - /* Try for ever and ever. */ - ABORT_INSTRUCTION; - } } - diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c index d5f83ee8e..280f42cb7 100644 --- a/libc/stdlib/atexit.c +++ b/libc/stdlib/atexit.c @@ -239,8 +239,7 @@ void exit(int rv) if (__app_fini != NULL) (__app_fini)(); #endif -#ifdef _DL_DO_FINI_IN_LIBC -/* arches that has moved their ldso FINI handling should #define _DL_DO_FINI_IN_LIBC */ +#ifndef _DL_FINI_CRT_COMPAT if (__rtld_fini != NULL) (__rtld_fini)(); #endif diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c index 68cd77665..ed14c37c4 100644 --- a/libc/stdlib/malloc-simple/alloc.c +++ b/libc/stdlib/malloc-simple/alloc.c @@ -1,6 +1,6 @@ /* alloc.c * - * Written by Erik Andersen <andersee@debian.org> + * Written by Erik Andersen <andersee@codepoet.org> * LGPLv2 * * Parts of the memalign code were stolen from malloc-930716. @@ -20,31 +20,29 @@ #ifdef L_malloc void *malloc(size_t size) { - void *result; + void *result; - if (unlikely(size == 0)) { + if (unlikely(size == 0)) { #if defined(__MALLOC_GLIBC_COMPAT__) - size++; + size++; #else - /* Some programs will call malloc (0). Lets be strict and return NULL */ - return 0; + /* Some programs will call malloc (0). Lets be strict and return NULL */ + return 0; #endif - } + } #ifdef __ARCH_HAS_MMU__ - result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - if (result == MAP_FAILED) - return 0; - * (size_t *) result = size; - return(result + sizeof(size_t)); +# define MMAP_FLAGS MAP_PRIVATE | MAP_ANONYMOUS #else - result = mmap((void *) 0, size, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS, 0, 0); - if (result == MAP_FAILED) - return 0; - return(result); +# define MMAP_FLAGS MAP_SHARED | MAP_ANONYMOUS #endif + + result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE, + MMAP_FLAGS, 0, 0); + if (result == MAP_FAILED) + return 0; + * (size_t *) result = size; + return(result + sizeof(size_t)); } #endif @@ -76,27 +74,21 @@ void * calloc(size_t nmemb, size_t lsize) #ifdef L_realloc void *realloc(void *ptr, size_t size) { - void *newptr = NULL; - - if (!ptr) - return malloc(size); - if (!size) { - free(ptr); - return malloc(0); - } - - newptr = malloc(size); - if (newptr) { - memcpy(newptr, ptr, -#ifdef __ARCH_HAS_MMU__ - *((size_t *) (ptr - sizeof(size_t))) -#else - size -#endif - ); - free(ptr); - } - return newptr; + void *newptr = NULL; + + if (!ptr) + return malloc(size); + if (!size) { + free(ptr); + return malloc(0); + } + + newptr = malloc(size); + if (newptr) { + memcpy(newptr, ptr, *((size_t *) (ptr - sizeof(size_t)))); + free(ptr); + } + return newptr; } #endif @@ -104,19 +96,14 @@ void *realloc(void *ptr, size_t size) extern int weak_function __libc_free_aligned(void *ptr); void free(void *ptr) { - if (ptr == NULL) - return; - if (unlikely(__libc_free_aligned!=NULL)) { - if (__libc_free_aligned(ptr)) { - return; + if (unlikely(ptr == NULL)) + return; + if (unlikely(__libc_free_aligned != NULL)) { + if (__libc_free_aligned(ptr)) + return; } - } -#ifdef __ARCH_HAS_MMU__ - ptr -= sizeof(size_t); - munmap(ptr, * (size_t *) ptr + sizeof(size_t)); -#else - munmap(ptr, 0); -#endif + ptr -= sizeof(size_t); + munmap(ptr, * (size_t *) ptr + sizeof(size_t)); } #endif @@ -134,73 +121,67 @@ pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; /* List of blocks allocated with memalign or valloc */ struct alignlist { - struct alignlist *next; - __ptr_t aligned; /* The address that memaligned returned. */ - __ptr_t exact; /* The address that malloc returned. */ + struct alignlist *next; + __ptr_t aligned; /* The address that memaligned returned. */ + __ptr_t exact; /* The address that malloc returned. */ }; struct alignlist *_aligned_blocks; /* Return memory to the heap. */ int __libc_free_aligned(void *ptr) { - struct alignlist *l; + struct alignlist *l; - if (ptr == NULL) - return 0; + if (ptr == NULL) + return 0; - LOCK; - for (l = _aligned_blocks; l != NULL; l = l->next) { - if (l->aligned == ptr) { - /* Mark the block as free */ - l->aligned = NULL; - ptr = l->exact; -#ifdef __ARCH_HAS_MMU__ - ptr -= sizeof(size_t); - munmap(ptr, * (size_t *) ptr + sizeof(size_t)); -#else - munmap(ptr, 0); -#endif - return 1; + LOCK; + for (l = _aligned_blocks; l != NULL; l = l->next) { + if (l->aligned == ptr) { + /* Mark the block as free */ + l->aligned = NULL; + ptr = l->exact; + ptr -= sizeof(size_t); + munmap(ptr, * (size_t *) ptr + sizeof(size_t)); + return 1; + } } - } - UNLOCK; - return 0; + UNLOCK; + return 0; } void * memalign (size_t alignment, size_t size) { - void * result; - unsigned long int adj; - - result = malloc (size + alignment - 1); - if (result == NULL) - return NULL; - adj = (unsigned long int) ((unsigned long int) ((char *) result - - (char *) NULL)) % alignment; - if (adj != 0) - { - struct alignlist *l; - LOCK; - for (l = _aligned_blocks; l != NULL; l = l->next) - if (l->aligned == NULL) - /* This slot is free. Use it. */ - break; - if (l == NULL) - { - l = (struct alignlist *) malloc (sizeof (struct alignlist)); - if (l == NULL) { - free(result); - UNLOCK; + void * result; + unsigned long int adj; + + result = malloc (size + alignment - 1); + if (result == NULL) return NULL; - } - l->next = _aligned_blocks; - _aligned_blocks = l; + + adj = (unsigned long int) ((unsigned long int) ((char *) result - + (char *) NULL)) % alignment; + if (adj != 0) { + struct alignlist *l; + LOCK; + for (l = _aligned_blocks; l != NULL; l = l->next) + if (l->aligned == NULL) + /* This slot is free. Use it. */ + break; + if (l == NULL) { + l = (struct alignlist *) malloc (sizeof (struct alignlist)); + if (l == NULL) { + free(result); + UNLOCK; + return NULL; + } + l->next = _aligned_blocks; + _aligned_blocks = l; + } + l->exact = result; + result = l->aligned = (char *) result + alignment - adj; + UNLOCK; } - l->exact = result; - result = l->aligned = (char *) result + alignment - adj; - UNLOCK; - } - return result; + return result; } #endif - diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c index 51e02a240..7025e8335 100644 --- a/libc/stdlib/malloc-standard/malloc.c +++ b/libc/stdlib/malloc-standard/malloc.c @@ -827,6 +827,10 @@ void* malloc(size_t bytes) mchunkptr bck; /* misc temp for linking */ void * sysmem; +#if !defined(__MALLOC_GLIBC_COMPAT__) + if (!bytes) return NULL; +#endif + LOCK; av = get_malloc_state(); /* diff --git a/libc/string/Makefile b/libc/string/Makefile index 4150e403e..6b516c1c5 100644 --- a/libc/string/Makefile +++ b/libc/string/Makefile @@ -39,8 +39,8 @@ MOBJ= basename.o bcopy.o bzero.o dirname.o ffs.o memccpy.o memchr.o memcmp.o \ stpncpy.o strcasecmp.o strcasestr.o strcat.o strchrnul.o strchr.o \ strcmp.o strcpy.o strcspn.o strdup.o strlen.o strncasecmp.o strncat.o \ strncmp.o strncpy.o strndup.o strnlen.o strpbrk.o strrchr.o strsep.o \ - strspn.o strstr.o strtok.o strtok_r.o strerror.o _susv3_strerror_r.o \ - _string_syserrmsgs.o _glibc_strerror_r.o \ + strspn.o strstr.o strtok.o strtok_r.o strerror.o __xpg_strerror_r.o \ + _string_syserrmsgs.o __glibc_strerror_r.o \ _string_syssigmsgs.o sys_siglist.o strsignal.o psignal.o \ __xpg_basename.o strlcat.o strlcpy.o sys_errlist.o memmem.o @@ -64,7 +64,7 @@ endif OBJS=$(MOBJ) $(MOBJx) ifeq ($(UCLIBC_HAS_WCHAR),y) -OBJS += $(MOBJW) $(MOBJWx) + OBJS += $(MOBJW) $(MOBJWx) endif OBJ_LIST=../obj.string diff --git a/libc/string/wstring.c b/libc/string/wstring.c index ed9ebb232..6f54ae615 100644 --- a/libc/string/wstring.c +++ b/libc/string/wstring.c @@ -1299,7 +1299,7 @@ char *strerror(int errnum) { static char buf[_STRERROR_BUFSIZE]; - _susv3_strerror_r(errnum, buf, sizeof(buf)); + __xpg_strerror_r(errnum, buf, sizeof(buf)); return buf; } @@ -1308,7 +1308,7 @@ char *strerror(int errnum) /**********************************************************************/ /* SUSv3 functions. */ /**********************************************************************/ -#ifdef L__susv3_strerror_r +#ifdef L___xpg_strerror_r #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__ #if defined(__alpha__) || defined(__mips__) || defined(__sparc__) @@ -1450,7 +1450,7 @@ static const unsigned char estridx[] = { #endif -int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen) +int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen) { register char *s; int i, retval; @@ -1528,7 +1528,7 @@ int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen) #else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */ -int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen) +int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen) { register char *s; int i, retval; @@ -1569,13 +1569,13 @@ int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen) /**********************************************************************/ /* GNU extension functions. */ /**********************************************************************/ -#ifdef L__glibc_strerror_r +#ifdef L___glibc_strerror_r -weak_alias(_glibc_strerror_r,__strerror_r); +weak_alias(__glibc_strerror_r,__strerror_r); -char *_glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen) +char *__glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen) { - _susv3_strerror_r(errnum, strerrbuf, buflen); + __xpg_strerror_r(errnum, strerrbuf, buflen); return strerrbuf; } diff --git a/libc/sysdeps/linux/common/Makefile b/libc/sysdeps/linux/common/Makefile index 5e17cc9fc..84b29ac53 100644 --- a/libc/sysdeps/linux/common/Makefile +++ b/libc/sysdeps/linux/common/Makefile @@ -28,6 +28,7 @@ endif ifneq ($(strip $(UCLIBC_HAS_SSP)),y) SRCS := $(filter-out ssp.c,$(SRCS)) endif +ssp.o: CFLAGS += $(SSP_DISABLE_FLAGS) OBJS = $(patsubst %.c,%.o, $(SRCS)) diff --git a/libc/sysdeps/linux/common/__syscall_fcntl.c b/libc/sysdeps/linux/common/__syscall_fcntl.c index 62568522b..0a5812976 100644 --- a/libc/sysdeps/linux/common/__syscall_fcntl.c +++ b/libc/sysdeps/linux/common/__syscall_fcntl.c @@ -11,10 +11,12 @@ #include <stdarg.h> #include <fcntl.h> -#define __NR___syscall_fcntl __NR_fcntl #ifdef __UCLIBC_HAS_LFS__ -static inline +extern int __libc_fcntl64(int fd, int cmd, long arg); #endif + +#define __NR___syscall_fcntl __NR_fcntl +static inline _syscall3(int, __syscall_fcntl, int, fd, int, cmd, long, arg); int __libc_fcntl(int fd, int cmd, ...) @@ -22,13 +24,18 @@ int __libc_fcntl(int fd, int cmd, ...) long arg; va_list list; + va_start(list, cmd); + arg = va_arg(list, long); + va_end(list); + if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) { +#ifdef __UCLIBC_HAS_LFS__ + return __libc_fcntl64(fd, cmd, arg); +#else __set_errno(ENOSYS); return -1; +#endif } - va_start(list, cmd); - arg = va_arg(list, long); - va_end(list); return (__syscall_fcntl(fd, cmd, arg)); } diff --git a/libc/sysdeps/linux/common/bits/errno.h b/libc/sysdeps/linux/common/bits/errno.h index d31dca8aa..cb9c2ee43 100644 --- a/libc/sysdeps/linux/common/bits/errno.h +++ b/libc/sysdeps/linux/common/bits/errno.h @@ -37,7 +37,7 @@ extern int errno; /* Function to get address of global `errno' variable. */ extern int *__errno_location (void) __THROW __attribute__ ((__const__)); -# if defined _LIBC && !defined(__set_errno) +# if defined _LIBC /* We wouldn't need a special macro anymore but it is history. */ # define __set_errno(val) ((errno) = (val)) # endif /* _LIBC */ diff --git a/libc/sysdeps/linux/common/bits/ipc.h b/libc/sysdeps/linux/common/bits/ipc.h index 7cd2fd0c5..f1a043fe5 100644 --- a/libc/sysdeps/linux/common/bits/ipc.h +++ b/libc/sysdeps/linux/common/bits/ipc.h @@ -38,19 +38,19 @@ /* Special key values. */ #define IPC_PRIVATE ((__key_t) 0) /* Private key. */ + /* Data structure used to pass permission information to IPC operations. */ struct ipc_perm { - __key_t __key; /* Key. */ - __uid_t uid; /* Owner's user ID. */ - __gid_t gid; /* Owner's group ID. */ - __uid_t cuid; /* Creator's user ID. */ - __gid_t cgid; /* Creator's group ID. */ - unsigned short int mode; /* Read/write permission. */ + __key_t __key; /* Key. */ + __uid_t uid; /* Owner's user ID. */ + __gid_t gid; /* Owner's group ID. */ + __uid_t cuid; /* Creator's user ID. */ + __gid_t cgid; /* Creator's group ID. */ + unsigned short int mode; /* Read/write permission. */ unsigned short int __pad1; - unsigned short int __seq; /* Sequence number. */ + unsigned short int __seq; /* Sequence number. */ unsigned short int __pad2; unsigned long int __unused1; unsigned long int __unused2; }; - diff --git a/libc/sysdeps/linux/common/bits/sem.h b/libc/sysdeps/linux/common/bits/sem.h index f900136f0..6193501e2 100644 --- a/libc/sysdeps/linux/common/bits/sem.h +++ b/libc/sysdeps/linux/common/bits/sem.h @@ -36,15 +36,16 @@ /* Data structure describing a set of semaphores. */ -struct semid_ds { - struct ipc_perm sem_perm; /* permissions .. see ipc.h */ - __kernel_time_t sem_otime; /* last semop time */ - __kernel_time_t sem_ctime; /* last change time */ - struct sem *sem_base; /* ptr to first semaphore in array */ - struct sem_queue *sem_pending; /* pending operations to be processed */ - struct sem_queue **sem_pending_last; /* last pending operation */ - struct sem_undo *undo; /* undo requests on this array */ - unsigned short sem_nsems; /* no. of semaphores in array */ +struct semid_ds +{ + struct ipc_perm sem_perm; /* operation permission struct */ + __time_t sem_otime; /* last semop() time */ + unsigned long int __unused1; + __time_t sem_ctime; /* last time changed by semctl() */ + unsigned long int __unused2; + unsigned long int sem_nsems; /* number of semaphores in set */ + unsigned long int __unused3; + unsigned long int __unused4; }; /* The user should define a union like the following to use it for arguments diff --git a/libc/sysdeps/linux/common/bits/sigthread.h b/libc/sysdeps/linux/common/bits/sigthread.h index 960bde18a..0a634ac68 100644 --- a/libc/sysdeps/linux/common/bits/sigthread.h +++ b/libc/sysdeps/linux/common/bits/sigthread.h @@ -1,18 +1,18 @@ /* Signal handling function for threaded programs. - Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 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 + 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 - Lesser General Public License for more details. + Library General Public License for more details. - You should have received a copy of the GNU Lesser General Public + 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. */ @@ -33,6 +33,6 @@ extern int pthread_sigmask (int __how, __sigset_t *__restrict __oldmask)__THROW; /* Send signal SIGNO to the given thread. */ -extern int pthread_kill (pthread_t __threadid, int __signo) __THROW; +extern int pthread_kill (pthread_t __thread_id, int __signo) __THROW; #endif /* bits/sigthread.h */ diff --git a/libc/sysdeps/linux/common/bits/stat.h b/libc/sysdeps/linux/common/bits/stat.h index 3ecec4a47..3e8e77f65 100644 --- a/libc/sysdeps/linux/common/bits/stat.h +++ b/libc/sysdeps/linux/common/bits/stat.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1992,95,96,97,98,99,2000,2001 Free Software Foundation, Inc. +/* Copyright (C) 1992, 1995-2001, 2002 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 @@ -63,11 +63,11 @@ struct stat __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif __time_t st_atime; /* Time of last access. */ - unsigned long int __unused1; + unsigned long int st_atimensec; /* Nscecs of last access. */ __time_t st_mtime; /* Time of last modification. */ - unsigned long int __unused2; + unsigned long int st_mtimensec; /* Nsecs of last modification. */ __time_t st_ctime; /* Time of last status change. */ - unsigned long int __unused3; + unsigned long int st_ctimensec; /* Nsecs of last status change. */ #ifndef __USE_FILE_OFFSET64 unsigned long int __unused4; unsigned long int __unused5; @@ -94,11 +94,11 @@ struct stat64 __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ __time_t st_atime; /* Time of last access. */ - unsigned long int __unused1; + unsigned long int st_atimensec; /* Nscecs of last access. */ __time_t st_mtime; /* Time of last modification. */ - unsigned long int __unused2; + unsigned long int st_mtimensec; /* Nsecs of last modification. */ __time_t st_ctime; /* Time of last status change. */ - unsigned long int __unused3; + unsigned long int st_ctimensec; /* Nsecs of last status change. */ __ino64_t st_ino; /* File serial number. */ }; #endif @@ -107,6 +107,8 @@ struct stat64 /* Tell code we have these members. */ #define _STATBUF_ST_BLKSIZE #define _STATBUF_ST_RDEV +/* Nanosecond resolution time values are supported. */ +#define _STATBUF_ST_NSEC /* Encoding of the file mode. */ diff --git a/libc/sysdeps/linux/common/ioperm.c b/libc/sysdeps/linux/common/ioperm.c index 8afba049e..874577a64 100644 --- a/libc/sysdeps/linux/common/ioperm.c +++ b/libc/sysdeps/linux/common/ioperm.c @@ -8,12 +8,12 @@ */ #include "syscalls.h" -# if defined __ARCH_HAS_MMU__ && defined __NR_ioperm +#if defined __ARCH_HAS_MMU__ && defined __NR_ioperm _syscall3(int, ioperm, unsigned long, from, unsigned long, num, int, turn_on); -# else +#else int ioperm(unsigned long from, unsigned long num, int turn_on) { __set_errno(ENOSYS); return -1; } -# endif +#endif diff --git a/libc/sysdeps/linux/common/pread_write.c b/libc/sysdeps/linux/common/pread_write.c index bf04be41f..05eff4bc9 100644 --- a/libc/sysdeps/linux/common/pread_write.c +++ b/libc/sysdeps/linux/common/pread_write.c @@ -186,7 +186,9 @@ weak_alias (__libc_pread64, pread64) #ifndef __NR_pwrite ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset) { - return(__fake_pread_write(fd, buf, count, offset, 1)); + /* we won't actually be modifying the buffer, + *just cast it to get rid of warnings */ + return(__fake_pread_write(fd, (void*)buf, count, offset, 1)); } weak_alias (__libc_pwrite, pwrite) diff --git a/libc/sysdeps/linux/common/ssp.c b/libc/sysdeps/linux/common/ssp.c index ecfc67e5e..31833cbb9 100644 --- a/libc/sysdeps/linux/common/ssp.c +++ b/libc/sysdeps/linux/common/ssp.c @@ -20,6 +20,10 @@ # include <config.h> #endif +#ifdef __SSP__ +# error ssp.c has to be built w/ -fno-stack-protector +#endif + #include <stdio.h> #include <string.h> #include <fcntl.h> @@ -30,29 +34,38 @@ #include <sys/syslog.h> #include <sys/time.h> #ifdef __SSP_USE_ERANDOM__ -#include <sys/sysctl.h> +# include <sys/sysctl.h> #endif #ifdef __PROPOLICE_BLOCK_SEGV__ -#define SSP_SIGTYPE SIGSEGV +# define SSP_SIGTYPE SIGSEGV #elif __PROPOLICE_BLOCK_KILL__ -#define SSP_SIGTYPE SIGKILL +# define SSP_SIGTYPE SIGKILL #else -#define SSP_SIGTYPE SIGABRT +# define SSP_SIGTYPE SIGABRT #endif -/* prototypes */ -extern int __libc_open (__const char *file, int oflag, mode_t mode); -extern ssize_t __libc_read(int fd, void *buf, size_t count); -extern int __libc_close (int fd); - unsigned long __guard = 0UL; +/* Use of __* functions from the rest of glibc here avoids + * initialisation problems for executables preloaded with + * libraries that overload the associated standard library + * functions. + */ +#ifdef __UCLIBC__ +extern int __libc_open(__const char *file, int flags, ...); +extern ssize_t __libc_read(int fd, void *buf, size_t count); +extern int __libc_close(int fd); +#else +# define __libc_open(file, flags) __open(file, flags) +# define __libc_read(fd, buf, count) __read(fd, buf, count) +# define __libc_close(fd) __close(fd) +#endif + void __guard_setup(void) __attribute__ ((constructor)); void __guard_setup(void) { size_t size; - struct timeval tv; if (__guard != 0UL) return; @@ -61,18 +74,20 @@ void __guard_setup(void) __guard = 0xFF0A0D00UL; #ifndef __SSP_QUICK_CANARY__ -#ifdef __SSP_USE_ERANDOM__ - int mib[3]; - /* Random is another depth in Linux, hence an array of 3. */ - mib[0] = CTL_KERN; - mib[1] = KERN_RANDOM; - mib[2] = RANDOM_ERANDOM; - - size = sizeof(unsigned long); - if (__sysctl(mib, 3, &__guard, &size, NULL, 0) != (-1)) - if (__guard != 0UL) - return; -#endif +# ifdef __SSP_USE_ERANDOM__ + { + int mib[3]; + /* Random is another depth in Linux, hence an array of 3. */ + mib[0] = CTL_KERN; + mib[1] = KERN_RANDOM; + mib[2] = RANDOM_ERANDOM; + + size = sizeof(unsigned long); + if (__sysctl(mib, 3, &__guard, &size, NULL, 0) != (-1)) + if (__guard != 0UL) + return; + } +# endif /* ifdef __SSP_USE_ERANDOM__ */ /* * Attempt to open kernel pseudo random device if one exists before * opening urandom to avoid system entropy depletion. @@ -80,9 +95,9 @@ void __guard_setup(void) { int fd; -#ifdef __SSP_USE_ERANDOM__ +# ifdef __SSP_USE_ERANDOM__ if ((fd = __libc_open("/dev/erandom", O_RDONLY)) == (-1)) -#endif +# endif fd = __libc_open("/dev/urandom", O_RDONLY); if (fd != (-1)) { size = __libc_read(fd, (char *) &__guard, sizeof(__guard)); @@ -91,13 +106,15 @@ void __guard_setup(void) return; } } -#endif +#endif /* ifndef __SSP_QUICK_CANARY__ */ /* Everything failed? Or we are using a weakened model of the * terminator canary */ - - gettimeofday(&tv, NULL); - __guard ^= tv.tv_usec ^ tv.tv_sec; + { + struct timeval tv; + gettimeofday(&tv, NULL); + __guard ^= tv.tv_usec ^ tv.tv_sec; + } } void __stack_smash_handler(char func[], int damaged __attribute__ ((unused))); diff --git a/libc/sysdeps/linux/common/umount.c b/libc/sysdeps/linux/common/umount.c index d8e890d8b..158aefc5f 100644 --- a/libc/sysdeps/linux/common/umount.c +++ b/libc/sysdeps/linux/common/umount.c @@ -9,26 +9,33 @@ #include "syscalls.h" -#ifdef __NR_umount /* Some newer archs only have umount2 */ + +/* arch provides umount() syscall */ +#ifdef __NR_umount + #include <sys/mount.h> _syscall1(int, umount, const char *, specialfile); + +/* arch provides umount2() syscall */ #elif defined __NR_umount2 -/* No umount syscall, but umount2 is available.... Try to - * emulate umount() using umount2() */ #define __NR___syscall_umount2 __NR_umount2 -static inline _syscall2(int, umount2, const char *, special_file, int, flags); +static inline _syscall2(int, __syscall_umount2, const char *, special_file, int, flags); int umount(const char *special_file) { return (__syscall_umount2(special_file, 0)); } + +/* arch doesn't provide any umount syscall !? */ #else + int umount(const char *special_file) { __set_errno(ENOSYS); return -1; } + #endif diff --git a/libc/sysdeps/linux/common/xstatconv.c b/libc/sysdeps/linux/common/xstatconv.c index fc25c43db..df6ebaa2b 100644 --- a/libc/sysdeps/linux/common/xstatconv.c +++ b/libc/sysdeps/linux/common/xstatconv.c @@ -34,42 +34,53 @@ void __xstat_conv(struct kernel_stat *kbuf, struct stat *buf) { - /* Convert to current kernel version of `struct stat'. */ - buf->st_dev = kbuf->st_dev; - buf->st_ino = kbuf->st_ino; - buf->st_mode = kbuf->st_mode; - buf->st_nlink = kbuf->st_nlink; - buf->st_uid = kbuf->st_uid; - buf->st_gid = kbuf->st_gid; - buf->st_rdev = kbuf->st_rdev; - buf->st_size = kbuf->st_size; - buf->st_blksize = kbuf->st_blksize; - buf->st_blocks = kbuf->st_blocks; - buf->st_atime = kbuf->st_atime; - buf->st_mtime = kbuf->st_mtime; - buf->st_ctime = kbuf->st_ctime; + /* Convert to current kernel version of `struct stat'. */ + buf->st_dev = kbuf->st_dev; + buf->st_ino = kbuf->st_ino; + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; + buf->st_size = kbuf->st_size; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; +#ifdef STAT_HAVE_NSEC + buf->st_atimensec = kbuf->st_atime_nsec; + buf->st_mtimensec = kbuf->st_mtime_nsec; + buf->st_ctimensec = kbuf->st_ctime_nsec; +#endif } -#if defined __UCLIBC_HAS_LFS__ +#if defined(__UCLIBC_HAS_LFS__) + void __xstat64_conv(struct kernel_stat64 *kbuf, struct stat64 *buf) { - /* Convert to current kernel version of `struct stat64'. */ - buf->st_dev = kbuf->st_dev; - buf->st_ino = kbuf->st_ino; + /* Convert to current kernel version of `struct stat64'. */ + buf->st_dev = kbuf->st_dev; + buf->st_ino = kbuf->st_ino; #ifdef _HAVE_STAT64___ST_INO - buf->__st_ino = kbuf->__st_ino; + buf->__st_ino = kbuf->__st_ino; #endif - buf->st_mode = kbuf->st_mode; - buf->st_nlink = kbuf->st_nlink; - buf->st_uid = kbuf->st_uid; - buf->st_gid = kbuf->st_gid; - buf->st_rdev = kbuf->st_rdev; - buf->st_size = kbuf->st_size; - buf->st_blksize = kbuf->st_blksize; - buf->st_blocks = kbuf->st_blocks; - buf->st_atime = kbuf->st_atime; - buf->st_mtime = kbuf->st_mtime; - buf->st_ctime = kbuf->st_ctime; -} + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; + buf->st_size = kbuf->st_size; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; +#ifdef STAT_HAVE_NSEC + buf->st_atimensec = kbuf->st_atime_nsec; + buf->st_mtimensec = kbuf->st_mtime_nsec; + buf->st_ctimensec = kbuf->st_ctime_nsec; #endif +} +#endif /* __UCLIBC_HAS_LFS__ */ diff --git a/libc/sysdeps/linux/mips/__syscall_error.c b/libc/sysdeps/linux/mips/__syscall_error.c index 9ab65ed79..de65a1f39 100644 --- a/libc/sysdeps/linux/mips/__syscall_error.c +++ b/libc/sysdeps/linux/mips/__syscall_error.c @@ -1,4 +1,4 @@ -/* Wrapper around clone system call. +/* Wrapper for setting errno. Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -18,12 +18,12 @@ 02111-1307 USA. */ #include <errno.h> +#include <features.h> /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error (int err_no) +int attribute_hidden __syscall_error(int err_no) { - __set_errno (err_no); + __set_errno(err_no); return -1; } - diff --git a/libc/sysdeps/linux/mips/bits/msq.h b/libc/sysdeps/linux/mips/bits/msq.h index c2c1dd2e8..2b0d38ec8 100644 --- a/libc/sysdeps/linux/mips/bits/msq.h +++ b/libc/sysdeps/linux/mips/bits/msq.h @@ -21,6 +21,7 @@ #endif #include <bits/types.h> +#include <bits/wordsize.h> /* Define options for message queue functions. */ #define MSG_NOERROR 010000 /* no error if message is too big */ @@ -38,16 +39,34 @@ typedef unsigned long int msglen_t; struct msqid_ds { struct ipc_perm msg_perm; /* structure describing operation permission */ +#if (__WORDSIZE == 32) && !defined(__MIPSEL__) + unsigned long __unused1; +#endif __time_t msg_stime; /* time of last msgsnd command */ +#if (__WORDSIZE == 32) && defined(__MIPSEL__) + unsigned long __unused1; +#endif +#if (__WORDSIZE == 32) && !defined(__MIPSEL__) + unsigned long __unused2; +#endif __time_t msg_rtime; /* time of last msgrcv command */ +#if (__WORDSIZE == 32) && defined(__MIPSEL__) + unsigned long __unused2; +#endif +#if (__WORDSIZE == 32) && !defined(__MIPSEL__) + unsigned long __unused3; +#endif __time_t msg_ctime; /* time of last change */ +#if (__WORDSIZE == 32) && defined(__MIPSEL__) + unsigned long __unused3; +#endif unsigned long int __msg_cbytes; /* current number of bytes on queue */ msgqnum_t msg_qnum; /* number of messages currently on queue */ msglen_t msg_qbytes; /* max number of bytes allowed on queue */ __pid_t msg_lspid; /* pid of last msgsnd() */ __pid_t msg_lrpid; /* pid of last msgrcv() */ - unsigned long int __unused1; - unsigned long int __unused2; + unsigned long int __unused4; + unsigned long int __unused5; }; #ifdef __USE_MISC diff --git a/libc/sysdeps/linux/mips/bsd-setjmp.S b/libc/sysdeps/linux/mips/bsd-setjmp.S index 51af9c891..49a904d29 100644 --- a/libc/sysdeps/linux/mips/bsd-setjmp.S +++ b/libc/sysdeps/linux/mips/bsd-setjmp.S @@ -34,8 +34,8 @@ .type setjmp,@function setjmp: -#ifdef __PIC__ .set noreorder +#ifdef __PIC__ .cpload t9 .set reorder la t9, __sigsetjmp diff --git a/libc/sysdeps/linux/mips/clone.S b/libc/sysdeps/linux/mips/clone.S index 3b879040a..079d2bef2 100644 --- a/libc/sysdeps/linux/mips/clone.S +++ b/libc/sysdeps/linux/mips/clone.S @@ -72,6 +72,11 @@ __clone: /* Something bad happened -- no child created */ error: addiu sp,32 + + /* uClibc change -- start */ + move a0,v0 /* Pass return val to C function. */ + /* uClibc change -- stop */ + #ifdef __PIC__ la t9,__syscall_error jr t9 |