diff options
Diffstat (limited to 'libc')
-rw-r--r-- | libc/inet/socketcalls.c | 24 | ||||
-rw-r--r-- | libc/signal/sigaction.c | 8 | ||||
-rw-r--r-- | libc/signal/sigset.c | 2 | ||||
-rw-r--r-- | libc/stdlib/Makefile | 2 | ||||
-rw-r--r-- | libc/stdlib/atexit.c | 137 | ||||
-rw-r--r-- | libc/stdlib/system.c | 3 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/longjmp.c | 7 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/syscalls.c | 72 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/wait.c | 5 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/waitpid.c | 3 | ||||
-rw-r--r-- | libc/sysdeps/linux/sh/longjmp.c | 9 | ||||
-rw-r--r-- | libc/termios/termios.c | 3 |
12 files changed, 201 insertions, 74 deletions
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index f784a1c47..c8313ade8 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -28,7 +28,7 @@ extern int socketcall(int call, unsigned long *args); #ifdef L_accept -int accept(int s, struct sockaddr *addr, socklen_t * addrlen) +int __libc_accept(int s, struct sockaddr *addr, socklen_t * addrlen) { unsigned long args[3]; @@ -37,6 +37,7 @@ int accept(int s, struct sockaddr *addr, socklen_t * addrlen) args[2] = (unsigned long) addrlen; return socketcall(SYS_ACCEPT, args); } +weak_alias(__libc_accept, accept); #endif #ifdef L_bind @@ -52,7 +53,7 @@ int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen) #endif #ifdef L_connect -int connect(int sockfd, const struct sockaddr *saddr, socklen_t addrlen) +int __libc_connect(int sockfd, const struct sockaddr *saddr, socklen_t addrlen) { unsigned long args[3]; @@ -61,6 +62,7 @@ int connect(int sockfd, const struct sockaddr *saddr, socklen_t addrlen) args[2] = addrlen; return socketcall(SYS_CONNECT, args); } +weak_alias(__libc_connect, connect); #endif #ifdef L_getpeername @@ -115,7 +117,7 @@ int listen(int sockfd, int backlog) #ifdef L_recv /* recv, recvfrom added by bir7@leland.stanford.edu */ -int recv(int sockfd, __ptr_t buffer, size_t len, int flags) +int __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags) { unsigned long args[4]; @@ -125,11 +127,12 @@ int recv(int sockfd, __ptr_t buffer, size_t len, int flags) args[3] = flags; return (socketcall(SYS_RECV, args)); } +weak_alias(__libc_recv, recv); #endif #ifdef L_recvfrom /* recv, recvfrom added by bir7@leland.stanford.edu */ -int recvfrom(int sockfd, __ptr_t buffer, size_t len, int flags, +int __libc_recvfrom(int sockfd, __ptr_t buffer, size_t len, int flags, struct sockaddr *to, socklen_t * tolen) { unsigned long args[6]; @@ -142,10 +145,11 @@ int recvfrom(int sockfd, __ptr_t buffer, size_t len, int flags, args[5] = (unsigned long) tolen; return (socketcall(SYS_RECVFROM, args)); } +weak_alias(__libc_recvfrom, recvfrom); #endif #ifdef L_recvmsg -int recvmsg(int sockfd, struct msghdr *msg, int flags) +int __libc_recvmsg(int sockfd, struct msghdr *msg, int flags) { unsigned long args[3]; @@ -154,11 +158,12 @@ int recvmsg(int sockfd, struct msghdr *msg, int flags) args[2] = flags; return (socketcall(SYS_RECVMSG, args)); } +weak_alias(__libc_recvmsg, recvmsg); #endif #ifdef L_send /* send, sendto added by bir7@leland.stanford.edu */ -int send(int sockfd, const void *buffer, size_t len, int flags) +int __libc_send(int sockfd, const void *buffer, size_t len, int flags) { unsigned long args[4]; @@ -168,10 +173,11 @@ int send(int sockfd, const void *buffer, size_t len, int flags) args[3] = flags; return (socketcall(SYS_SEND, args)); } +weak_alias(__libc_send, send); #endif #ifdef L_sendmsg -int sendmsg(int sockfd, const struct msghdr *msg, int flags) +int __libc_sendmsg(int sockfd, const struct msghdr *msg, int flags) { unsigned long args[3]; @@ -180,11 +186,12 @@ int sendmsg(int sockfd, const struct msghdr *msg, int flags) args[2] = flags; return (socketcall(SYS_SENDMSG, args)); } +weak_alias(__libc_sendmsg, sendmsg); #endif #ifdef L_sendto /* send, sendto added by bir7@leland.stanford.edu */ -int sendto(int sockfd, const void *buffer, size_t len, int flags, +int __libc_sendto(int sockfd, const void *buffer, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) { unsigned long args[6]; @@ -197,6 +204,7 @@ int sendto(int sockfd, const void *buffer, size_t len, int flags, args[5] = tolen; return (socketcall(SYS_SENDTO, args)); } +weak_alias(__libc_sendto, sendto); #endif #ifdef L_setsockopt diff --git a/libc/signal/sigaction.c b/libc/signal/sigaction.c index cf58edf39..80cd68798 100644 --- a/libc/signal/sigaction.c +++ b/libc/signal/sigaction.c @@ -119,7 +119,7 @@ extern int __rt_sigaction (int, const struct kernel_sigaction *__unbounded, /* If ACT is not NULL, change the action for SIG to *ACT. If OACT is not NULL, put the old action for SIG in *OACT. */ -int sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) { int result; struct kernel_sigaction kact, koact; @@ -148,7 +148,7 @@ int sigaction (int sig, const struct sigaction *act, struct sigaction *oact) } return result; } - +weak_alias(__libc_sigaction, sigaction) @@ -160,7 +160,7 @@ extern int __sigaction (int, const struct old_kernel_sigaction *__unbounded, /* If ACT is not NULL, change the action for SIG to *ACT. If OACT is not NULL, put the old action for SIG in *OACT. */ -int sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) { struct old_kernel_sigaction k_sigact, k_osigact; int result; @@ -187,4 +187,6 @@ int sigaction (int sig, const struct sigaction *act, struct sigaction *oact) return result; } +weak_alias(__libc_sigaction, sigaction) + #endif diff --git a/libc/signal/sigset.c b/libc/signal/sigset.c index a5afa17f3..e0cda7b9f 100644 --- a/libc/signal/sigset.c +++ b/libc/signal/sigset.c @@ -41,7 +41,7 @@ __sighandler_t sigset (int sig, __sighandler_t disp) return SIG_ERR; /* Add the signal set to the current signal mask. */ - if (__sigprocmask (SIG_BLOCK, &set, NULL) < 0) + if (sigprocmask (SIG_BLOCK, &set, NULL) < 0) return SIG_ERR; return SIG_HOLD; diff --git a/libc/stdlib/Makefile b/libc/stdlib/Makefile index 8e36fd18e..aaf959bcc 100644 --- a/libc/stdlib/Makefile +++ b/libc/stdlib/Makefile @@ -34,7 +34,7 @@ MSRC1=strto_ll.c MOBJ1=strtoll.o strtoull.o strto_ll.o atoll.o MSRC2=atexit.c -MOBJ2=atexit.o exit.o +MOBJ2=atexit.o on_exit.o __exit_handler.o exit.o CSRC = abort.c getenv.c mktemp.c qsort.c realpath.c abs.c bsearch.c \ diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c index 45ecefe9c..d7be35fbd 100644 --- a/libc/stdlib/atexit.c +++ b/libc/stdlib/atexit.c @@ -10,7 +10,7 @@ * Removed on_exit since it did not match gnu libc definition. * Combined atexit and __do_exit into one object file. * - * Feb 2000 Manuel Novoa III + * Feb 2001 Manuel Novoa III * * Reworked file after addition of __uClibc_main. * Changed name of __do_exit to atexit_handler. @@ -18,58 +18,149 @@ * Moved declaration of __uClibc_cleanup to __uClibc_main * where it is initialized with (possibly weak alias) * __stdio_close_all. + * + * Jul 2001 Steve Thayer + * + * Added an on_exit implementation (that now matches gnu libc definition.) + * Pulled atexit_handler out of the atexit object since it is now required by + * on_exit as well. Renamed it to __exit_handler. + * Fixed a problem where exit functions stop getting called if one of + * them calls exit(). + * As a side effect of these changes, abort() no longer calls the exit + * functions (it now matches the gnu libc definition). + * */ #include <unistd.h> #include <stdlib.h> #include <errno.h> -typedef void (*vfuncp) (void); -extern vfuncp __uClibc_cleanup; +#define __MAX_EXIT __UCLIBC_MAX_ATEXIT + +typedef void (*aefuncp) (void); /* atexit function pointer */ +typedef void (*oefuncp) (int, void *); /* on_exit function pointer */ +typedef enum { + ef_atexit, + ef_on_exit +} ef_type; /* exit function types */ -#ifdef L_atexit extern void __stdio_close_all(void); -static vfuncp __atexit_table[__UCLIBC_MAX_ATEXIT]; -static int __atexit_count = 0; +/* this is in the L_exit object */ +extern void (*__exit_cleanup) (int); -static void atexit_handler(void) -{ - int count; +/* these are in the L___do_exit object */ +extern int __exit_count; +extern void __exit_handler(int); +extern struct exit_function { + ef_type type; /* ef_atexit or ef_on_exit */ + union { + aefuncp atexit; + struct { + oefuncp func; + void *arg; + } on_exit; + } funcs; +} __exit_function_table[__MAX_EXIT]; +#ifdef L_atexit /* - * Guard against more functions being added and againt being reinvoked. + * register a function to be called at normal program termination + * (the registered function takes no arguments) */ - __uClibc_cleanup = 0; +int atexit(aefuncp func) +{ + struct exit_function *efp; - /* In reverse order */ - for (count = __atexit_count ; count-- ; ) { - (*__atexit_table[count])(); + if (__exit_count >= __MAX_EXIT) { + __set_errno(ENOMEM); + return -1; } - if (__stdio_close_all) - __stdio_close_all(); + if (func) { + __exit_cleanup = __exit_handler; /* enable cleanup */ + efp = &__exit_function_table[__exit_count++]; + efp->type = ef_atexit; + efp->funcs.atexit = func; + } + return 0; } +#endif -int atexit(vfuncp ptr) +#ifdef L_on_exit +/* + * register a function to be called at normal program termination + * the registered function takes two arguments: + * status - the exit status that was passed to the exit() function + * arg - generic argument + */ +int on_exit(oefuncp func, void *arg) { - if ((__uClibc_cleanup == 0) || (__atexit_count >= __UCLIBC_MAX_ATEXIT)) { + struct exit_function *efp; + + if (__exit_count >= __MAX_EXIT) { __set_errno(ENOMEM); return -1; } - if (ptr) { - __uClibc_cleanup = atexit_handler; - __atexit_table[__atexit_count++] = ptr; + if (func) { + __exit_cleanup = __exit_handler; /* enable cleanup */ + efp = &__exit_function_table[__exit_count++]; + efp->type = ef_on_exit; + efp->funcs.on_exit.func = func; + efp->funcs.on_exit.arg = arg; } return 0; } #endif +#ifdef L___exit_handler +struct exit_function __exit_function_table[__MAX_EXIT]; +int __exit_count = 0; /* Number of registered exit functions */ + +/* + * Handle the work of executing the registered exit functions + */ +void __exit_handler(int status) +{ + struct exit_function *efp; + + /* In reverse order */ + for ( ; __exit_count-- ; ) { + efp = &__exit_function_table[__exit_count]; + switch (efp->type) { + case ef_on_exit: + if (efp->funcs.on_exit.func) { + (efp->funcs.on_exit.func) (status, efp->funcs.on_exit.arg); + } + break; + case ef_atexit: + if (efp->funcs.atexit) { + (efp->funcs.atexit) (); + } + break; + } + } + if (__stdio_close_all) + __stdio_close_all(); +} +#endif + #ifdef L_exit +extern void (*__uClibc_cleanup) (void); +void (*__exit_cleanup) (int) = 0; + +/* + * Normal program termination + */ void exit(int rv) { - if (__uClibc_cleanup) { /* Not already executing __uClibc_cleanup. */ - __uClibc_cleanup(); + /* Perform exit-specific cleanup (atexit and on_exit) */ + if (__exit_cleanup) { + __exit_cleanup(rv); } + + /* Clean up everything else */ + __uClibc_cleanup(); + _exit(rv); } #endif diff --git a/libc/stdlib/system.c b/libc/stdlib/system.c index 5b279976c..6126d8114 100644 --- a/libc/stdlib/system.c +++ b/libc/stdlib/system.c @@ -4,7 +4,7 @@ #include <unistd.h> #include <sys/wait.h> -int system(command) +int __libc_system(command) char *command; { int wait_val, pid; @@ -47,3 +47,4 @@ char *command; signal(SIGCHLD, save_chld); return wait_val; } +weak_alias(__libc_system, system) diff --git a/libc/sysdeps/linux/common/longjmp.c b/libc/sysdeps/linux/common/longjmp.c index 3502a0323..e416865f2 100644 --- a/libc/sysdeps/linux/common/longjmp.c +++ b/libc/sysdeps/linux/common/longjmp.c @@ -27,7 +27,7 @@ extern void __longjmp (__jmp_buf __env, int val); /* Set the signal mask to the one specified in ENV, and jump to the position specified in ENV, causing the setjmp call there to return VAL, or 1 if VAL is 0. */ -void longjmp (sigjmp_buf env, int val) +void __libc_longjmp (sigjmp_buf env, int val) { #if 0 /* Perform any cleanups needed by the frames being unwound. */ @@ -43,5 +43,6 @@ void longjmp (sigjmp_buf env, int val) __longjmp (env[0].__jmpbuf, val ?: 1); } -weak_alias (longjmp, _longjmp) -weak_alias (longjmp, siglongjmp) +weak_alias (__libc_longjmp, _longjmp) +weak_alias (__libc_longjmp, siglongjmp) +weak_alias (__libc_longjmp, __libc_siglongjmp) diff --git a/libc/sysdeps/linux/common/syscalls.c b/libc/sysdeps/linux/common/syscalls.c index bb4bb109e..30426a419 100644 --- a/libc/sysdeps/linux/common/syscalls.c +++ b/libc/sysdeps/linux/common/syscalls.c @@ -22,8 +22,8 @@ * */ -#include <errno.h> #include <features.h> +#include <errno.h> #include <sys/types.h> #include <sys/syscall.h> @@ -39,10 +39,12 @@ _syscall1(void, _exit, int, status); #endif //#define __NR_fork 2 -#ifdef L_fork +#ifdef L___libc_fork #include <unistd.h> # ifdef __UCLIBC_HAS_MMU__ - _syscall0(pid_t, fork); +#define __NR___libc_fork __NR_fork + _syscall0(pid_t, __libc_fork); + weak_alias (__libc_fork, fork) # else pid_t fork(void) { @@ -53,16 +55,19 @@ _syscall1(void, _exit, int, status); #endif //#define __NR_read 3 -#ifdef L_read +#ifdef L___libc_read #include <unistd.h> -_syscall3(ssize_t, read, int, fd, __ptr_t, buf, size_t, count); +#define __NR___libc_read __NR_read +_syscall3(ssize_t, __libc_read, int, fd, __ptr_t, buf, size_t, count); +weak_alias(__libc_read, read) #endif //#define __NR_write 4 -#ifdef L_write +#ifdef L___libc_write #include <unistd.h> -_syscall3(ssize_t, write, int, fd, const __ptr_t, buf, size_t, count); -weak_alias(write, __write); +#define __NR___libc_write __NR_write +_syscall3(ssize_t, __libc_write, int, fd, const __ptr_t, buf, size_t, count); +weak_alias(__libc_write, write) #endif //#define __NR_open 5 @@ -75,7 +80,7 @@ weak_alias(write, __write); #endif _syscall3(int, __open, const char *, fn, int, flags, mode_t, mode); -int open(const char *file, int oflag, ...) +int __libc_open(const char *file, int oflag, ...) { int mode = 0; @@ -90,12 +95,15 @@ int open(const char *file, int oflag, ...) return __open(file, oflag, mode); } +weak_alias(__libc_open, open) #endif //#define __NR_close 6 -#ifdef L_close +#ifdef L___libc_close #include <unistd.h> -_syscall1(int, close, int, fd); +#define __NR___libc_close __NR_close +_syscall1(int, __libc_close, int, fd); +weak_alias(__libc_close, close) #endif //#define __NR_waitpid 7 @@ -182,15 +190,20 @@ _syscall3(int, lchown, const char *, path, uid_t, owner, gid_t, group); //#define __NR_oldstat 18 //#define __NR_lseek 19 -#ifdef L_lseek +#ifdef L___libc_lseek #include <unistd.h> -_syscall3(off_t, lseek, int, fildes, off_t, offset, int, whence); +#define __NR___libc_lseek __NR_lseek +_syscall3(off_t, __libc_lseek, int, fildes, off_t, offset, int, whence); +weak_alias(__libc_lseek, lseek) #endif //#define __NR_getpid 20 -#ifdef L_getpid +#ifdef L___libc_getpid #include <unistd.h> -_syscall0(pid_t, getpid); +#define __NR___libc_getpid __NR_getpid +_syscall0(pid_t, __libc_getpid); +weak_alias(__libc_getpid, getpid) +weak_alias(__libc_getpid, __getpid) #endif //#define __NR_mount 21 @@ -256,9 +269,11 @@ _syscall1(unsigned int, alarm, unsigned int, seconds); //#define __NR_oldfstat 28 //#define __NR_pause 29 -#ifdef L_pause +#ifdef L___libc_pause #include <unistd.h> -_syscall0(int, pause); +#define __NR___libc_pause __NR_pause +_syscall0(int, __libc_pause); +weak_alias(__libc_pause, pause) #endif //#define __NR_utime 30 @@ -458,7 +473,7 @@ extern int _fcntl(int fd, int cmd, long arg); _syscall3(int, _fcntl, int, fd, int, cmd, long, arg); -int fcntl(int fd, int command, ...) +int __libc_fcntl(int fd, int command, ...) { long arg; va_list list; @@ -469,6 +484,7 @@ int fcntl(int fd, int command, ...) va_end(list); return _fcntl(fd, command, arg); } +weak_alias(__libc_fcntl, fcntl) #endif //#define __NR_mpx 56 @@ -951,9 +967,11 @@ _syscall5(int, __ipc, unsigned int, call, int, first, int, second, int, third, v #endif //#define __NR_fsync 118 -#ifdef L_fsync +#ifdef L___libc_fsync #include <unistd.h> -_syscall1(int, fsync, int, fd); +#define __NR___libc_fsync __NR_fsync +_syscall1(int, __libc_fsync, int, fd); +weak_alias(__libc_fsync, fsync) #endif //#define __NR_sigreturn 119 @@ -1123,6 +1141,11 @@ _syscall2(int,flock,int,fd, int,operation); #endif //#define __NR_msync 144 +/* If this ever gets implemented, be sure to use the __libc_ convention + * so that it can be over-ridden with a cancelable version by linuxthreads. + * Also update uClibc/libpthread/linuxthreads/wrapsyscall.c to do the override. + */ + //#define __NR_readv 145 #ifdef L_readv @@ -1251,17 +1274,18 @@ _syscall2(int, sched_rr_get_interval, pid_t, pid, struct timespec *, tp); #endif //#define __NR_nanosleep 162 -#ifdef L_nanosleep +#ifdef L___libc_nanosleep #include <time.h> -_syscall2(int, nanosleep, const struct timespec *, req, struct timespec *, rem); +#define __NR___libc_nanosleep __NR_nanosleep +_syscall2(int, __libc_nanosleep, const struct timespec *, req, struct timespec *, rem); +weak_alias(__libc_nanosleep, nanosleep) #endif //#define __NR_mremap 163 #ifdef L_mremap #include <unistd.h> #include <sys/mman.h> -_syscall4(__ptr_t, mremap, __ptr_t, old_address, size_t, old_size, size_t, - new_size, int, may_move); +_syscall4(__ptr_t, mremap, __ptr_t, old_address, size_t, old_size, size_t, new_size, int, may_move); #endif //#define __NR_setresuid 164 diff --git a/libc/sysdeps/linux/common/wait.c b/libc/sysdeps/linux/common/wait.c index 13f9e148e..6c46d0caa 100644 --- a/libc/sysdeps/linux/common/wait.c +++ b/libc/sysdeps/linux/common/wait.c @@ -6,9 +6,8 @@ /* Wait for a child to die. When one does, put its status in *STAT_LOC * and return its process ID. For errors, return (pid_t) -1. */ -__pid_t wait (__WAIT_STATUS_DEFN stat_loc) +__pid_t __libc_wait (__WAIT_STATUS_DEFN stat_loc) { return wait4 (WAIT_ANY, stat_loc, 0, (struct rusage *) NULL); } - - +weak_alias(__libc_wait, wait) diff --git a/libc/sysdeps/linux/common/waitpid.c b/libc/sysdeps/linux/common/waitpid.c index a912e5179..fef93173b 100644 --- a/libc/sysdeps/linux/common/waitpid.c +++ b/libc/sysdeps/linux/common/waitpid.c @@ -4,7 +4,8 @@ #include <sys/wait.h> #include <sys/resource.h> -__pid_t waitpid(__pid_t pid, int *wait_stat, int options) +__pid_t __libc_waitpid(__pid_t pid, int *wait_stat, int options) { return wait4(pid, wait_stat, options, NULL); } +weak_alias(__libc_waitpid, waitpid) diff --git a/libc/sysdeps/linux/sh/longjmp.c b/libc/sysdeps/linux/sh/longjmp.c index 5395d5568..9c81e0432 100644 --- a/libc/sysdeps/linux/sh/longjmp.c +++ b/libc/sysdeps/linux/sh/longjmp.c @@ -28,8 +28,7 @@ /* Set the signal mask to the one specified in ENV, and jump to the position specified in ENV, causing the setjmp call there to return VAL, or 1 if VAL is 0. */ -void -__uClibc_siglongjmp (sigjmp_buf env, int val) +void __libc_siglongjmp (sigjmp_buf env, int val) { if (env[0].__mask_was_saved) /* Restore the saved signal mask. */ @@ -40,7 +39,7 @@ __uClibc_siglongjmp (sigjmp_buf env, int val) __longjmp (env[0].__jmpbuf, val ?: 1); } -__asm__(".weak longjmp; longjmp = __uClibc_siglongjmp"); -__asm__(".weak _longjmp; _longjmp = __uClibc_siglongjmp"); -__asm__(".weak siglongjmp; siglongjmp = __uClibc_siglongjmp"); +__asm__(".weak longjmp; longjmp = __libc_siglongjmp"); +__asm__(".weak _longjmp; _longjmp = __libc_siglongjmp"); +__asm__(".weak siglongjmp; siglongjmp = __libc_siglongjmp"); __asm__(".weak __sigprocmask; __sigprocmask = sigprocmask"); diff --git a/libc/termios/termios.c b/libc/termios/termios.c index 24448c0e4..08bf0991b 100644 --- a/libc/termios/termios.c +++ b/libc/termios/termios.c @@ -42,11 +42,12 @@ int isatty(int fd) #ifdef L_tcdrain /* Wait for pending output to be written on FD. */ -int tcdrain (int fd) +int __libc_tcdrain (int fd) { /* With an argument of 1, TCSBRK waits for the output to drain. */ return ioctl(fd, TCSBRK, 1); } +weak_alias(__libc_tcdrain, tcdrain) #endif #ifdef L_tcflow |