diff options
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 |