diff options
author | "Steven J. Hill" <sjhill@realitydiluted.com> | 2006-08-24 02:58:45 +0000 |
---|---|---|
committer | "Steven J. Hill" <sjhill@realitydiluted.com> | 2006-08-24 02:58:45 +0000 |
commit | 01f422c12f5799a44832eb26967a906edfc2ba55 (patch) | |
tree | 1e8bdcaab1f4da088cc1c490bf96c361a663e0c4 /libc/sysdeps/linux | |
parent | d2db9bdb4c79afcd4b09353346cd4eaf63b6cd2c (diff) | |
download | uClibc-alpine-01f422c12f5799a44832eb26967a906edfc2ba55.tar.bz2 uClibc-alpine-01f422c12f5799a44832eb26967a906edfc2ba55.tar.xz |
Well, this is everything for my NPTL implementation. The 'uClibc-nptl' branch is now the exact code that I have. I am going to re-run tests now to verify everything one more time. The next step after that is to merge from trunk with the latest stuff from Mike and Peter.
Diffstat (limited to 'libc/sysdeps/linux')
57 files changed, 1024 insertions, 405 deletions
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index f468222af..5d034795c 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -10,6 +10,9 @@ #include "syscalls.h" #include <signal.h> +#include <string.h> + +libc_hidden_proto(memcpy) #ifdef __NR_rt_sigtimedwait @@ -30,7 +33,7 @@ static int do_sigtimedwait(const sigset_t *set, siginfo_t *info, { /* Create a temporary mask without the bit for SIGCANCEL set. */ // We are not copying more than we have to. - __memcpy (&tmpset, set, _NSIG / 8); + memcpy (&tmpset, set, _NSIG / 8); __sigdelset (&tmpset, SIGCANCEL); # ifdef SIGSETXID __sigdelset (&tmpset, SIGSETXID); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index 81c34435f..c9a497503 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -10,6 +10,9 @@ #include "syscalls.h" #include <signal.h> +#include <string.h> + +libc_hidden_proto(memcpy) #ifdef __NR_rt_sigtimedwait @@ -29,7 +32,7 @@ static int do_sigwaitinfo(const sigset_t *set, siginfo_t *info) { /* Create a temporary mask without the bit for SIGCANCEL set. */ // We are not copying more than we have to. - __memcpy (&tmpset, set, _NSIG / 8); + memcpy (&tmpset, set, _NSIG / 8); __sigdelset (&tmpset, SIGCANCEL); # ifdef SIGSETXID __sigdelset (&tmpset, SIGSETXID); diff --git a/libc/sysdeps/linux/common/__syscall_fcntl.c b/libc/sysdeps/linux/common/__syscall_fcntl.c index ca9aff5e7..56a282a6a 100644 --- a/libc/sysdeps/linux/common/__syscall_fcntl.c +++ b/libc/sysdeps/linux/common/__syscall_fcntl.c @@ -2,49 +2,91 @@ /* * __syscall_fcntl() for uClibc * - * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> + * Copyright (C) 2006 Steven J. Hill <sjhill@realitydiluted.com> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> * * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ #include "syscalls.h" #include <stdarg.h> +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <sysdep-cancel.h> /* Must come before <fcntl.h>. */ +#endif #include <fcntl.h> +#include <bits/wordsize.h> -#undef __fcntl +extern __typeof(fcntl) __libc_fcntl; +libc_hidden_proto(__libc_fcntl) -#if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64 -extern int __fcntl64(int fd, int cmd, ...) attribute_hidden; -#endif +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +int __fcntl_nocancel (int fd, int cmd, ...) +{ + va_list ap; + void *arg; + + va_start (ap, cmd); + arg = va_arg (ap, void *); + va_end (ap); -#undef fcntl -#define __NR___syscall_fcntl __NR_fcntl -static inline -_syscall3(int, __syscall_fcntl, int, fd, int, cmd, long, arg); +# if __WORDSIZE == 32 + if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) { +# if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64 + return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg); +# else + __set_errno(ENOSYS); + return -1; +# endif + } +# endif + return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg); +} +#endif -int attribute_hidden __fcntl(int fd, int cmd, ...) +int __libc_fcntl (int fd, int cmd, ...) { - long arg; - va_list list; + va_list ap; + void *arg; - va_start(list, cmd); - arg = va_arg(list, long); - va_end(list); + va_start (ap, cmd); + arg = va_arg (ap, void *); + va_end (ap); - if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) { -#if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64 - return __fcntl64(fd, cmd, arg); +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ + if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64)) +# if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64 + return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg); +# else + return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg); +# endif + + int oldtype = LIBC_CANCEL_ASYNC (); + +# if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64 + int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg); +# else + int result = INLINE_SYSCALL (fcntl, 3, fd, cmd, arg); +# endif + + LIBC_CANCEL_RESET (oldtype); + + return result; #else +# if __WORDSIZE == 32 + if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) { +# if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64 + return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg); +# else __set_errno(ENOSYS); return -1; -#endif +# endif } - return (__syscall_fcntl(fd, cmd, arg)); -} -strong_alias(__fcntl,fcntl) -weak_alias(__fcntl,__libc_fcntl) -#if ! defined __NR_fcntl64 && defined __UCLIBC_HAS_LFS__ -hidden_strong_alias(__fcntl,__fcntl64) -weak_alias(__fcntl,fcntl64) -weak_alias(__fcntl,__libc_fcntl64) +# endif + return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg); #endif +} +libc_hidden_def(__libc_fcntl) + +libc_hidden_proto(fcntl) +weak_alias(__libc_fcntl,fcntl) +libc_hidden_weak(fcntl) diff --git a/libc/sysdeps/linux/common/_exit.c b/libc/sysdeps/linux/common/_exit.c index 4e450bbc5..4614ef9e0 100644 --- a/libc/sysdeps/linux/common/_exit.c +++ b/libc/sysdeps/linux/common/_exit.c @@ -2,29 +2,22 @@ /* * exit syscall for uClibc * - * Copyright (C) 2002 by Erik Andersen <andersen@codepoet.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Library General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License - * for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com> + * Copyright (C) 2002-2006 by Erik Andersen <andersen@codepoet.org> * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -#define _GNU_SOURCE #include <features.h> #include <errno.h> +#include <unistd.h> #include <sys/types.h> #include <sys/syscall.h> +#ifdef __UCLIBC_HAS_THREADS__ +#include <sysdep.h> +#endif + +libc_hidden_proto(_exit) #ifndef INLINE_SYSCALL #define INLINE_SYSCALL(name, nr, args...) __syscall_exit (args) @@ -32,12 +25,17 @@ static inline _syscall1(void, __syscall_exit, int, status); #endif -#undef _exit -#undef _exit_internal -void attribute_noreturn attribute_hidden _exit_internal(int status) +void attribute_noreturn _exit(int status) { /* The loop is added only to keep gcc happy. */ while(1) + { +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +# ifdef __NR_exit_group + INLINE_SYSCALL(exit_group, 1, status); +# endif +#endif INLINE_SYSCALL(exit, 1, status); + } } -strong_alias(_exit_internal,_exit) +libc_hidden_def(_exit) diff --git a/libc/sysdeps/linux/common/acct.c b/libc/sysdeps/linux/common/acct.c index 5c64623fb..2e7d1c600 100644 --- a/libc/sysdeps/linux/common/acct.c +++ b/libc/sysdeps/linux/common/acct.c @@ -9,4 +9,6 @@ #include "syscalls.h" #include <unistd.h> +#if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98) _syscall1(int, acct, const char *, filename); +#endif diff --git a/libc/sysdeps/linux/common/bits/errno.h b/libc/sysdeps/linux/common/bits/errno.h index 03d4729f6..f5831ef4d 100644 --- a/libc/sysdeps/linux/common/bits/errno.h +++ b/libc/sysdeps/linux/common/bits/errno.h @@ -19,7 +19,7 @@ #ifdef _ERRNO_H -# include <bits/errno_values.h> +#include <bits/errno_values.h> #ifndef ENOTSUP # define ENOTSUP EOPNOTSUPP diff --git a/libc/sysdeps/linux/common/bits/kernel_sigaction.h b/libc/sysdeps/linux/common/bits/kernel_sigaction.h index 5baf1e224..2fdfc897e 100644 --- a/libc/sysdeps/linux/common/bits/kernel_sigaction.h +++ b/libc/sysdeps/linux/common/bits/kernel_sigaction.h @@ -1,5 +1,5 @@ -#ifndef _BITS_STAT_STRUCT_H -#define _BITS_STAT_STRUCT_H +#ifndef _BITS_SIGACTION_STRUCT_H +#define _BITS_SIGACTION_STRUCT_H /* This file provides whatever this particular arch's kernel thinks * the sigaction struct should look like... */ @@ -59,10 +59,10 @@ struct kernel_sigaction { #ifndef NO_OLD_SIGACTION extern int __syscall_sigaction (int, const struct old_kernel_sigaction *__unbounded, - struct old_kernel_sigaction *__unbounded); + struct old_kernel_sigaction *__unbounded) attribute_hidden; #endif extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *__unbounded, - struct kernel_sigaction *__unbounded, size_t); + struct kernel_sigaction *__unbounded, size_t) attribute_hidden; -#endif /* _BITS_STAT_STRUCT_H */ +#endif /* _BITS_SIGACTION_STRUCT_H */ diff --git a/libc/sysdeps/linux/common/bits/poll.h b/libc/sysdeps/linux/common/bits/poll.h index dccb8b666..d7996b46c 100644 --- a/libc/sysdeps/linux/common/bits/poll.h +++ b/libc/sysdeps/linux/common/bits/poll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2001, 2006 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 @@ -36,8 +36,10 @@ #endif #ifdef __USE_GNU -/* This is an extension for Linux. */ +/* These are extensions for Linux. */ # define POLLMSG 0x400 +# define POLLREMOVE 0x1000 +# define POLLRDHUP 0x2000 #endif /* Event types always implicitly polled for. These bits need not be set in diff --git a/libc/sysdeps/linux/common/bits/posix_opt.h b/libc/sysdeps/linux/common/bits/posix_opt.h index b2cae9d41..ce416c9dd 100644 --- a/libc/sysdeps/linux/common/bits/posix_opt.h +++ b/libc/sysdeps/linux/common/bits/posix_opt.h @@ -58,7 +58,7 @@ /* Setting of memory protections is supported. */ #ifdef __ARCH_USE_MMU__ -# define _POSIX_MEMORY_PROTECTION 1 +# define _POSIX_MEMORY_PROTECTION 200112L #else # undef _POSIX_MEMORY_PROTECTION #endif @@ -101,7 +101,7 @@ /* We have the reentrant functions described in POSIX. */ #ifdef __UCLIBC_HAS_THREADS__ -# define _POSIX_REENTRANT_FUNCTIONS 1 +# define _POSIX_REENTRANT_FUNCTIONS 1 # define _POSIX_THREAD_SAFE_FUNCTIONS 1 #else # undef _POSIX_REENTRANT_FUNCTIONS @@ -165,6 +165,14 @@ # define _POSIX_THREAD_CPUTIME 200912L #endif +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +/* CPU-time clocks support needs to be checked at runtime. */ +#define _POSIX_CPUTIME 0 + +/* Clock support in threads must be also checked at runtime. */ +#define _POSIX_THREAD_CPUTIME 0 +#endif + /* Reader/Writer locks are available. */ #define _POSIX_READER_WRITER_LOCKS 200912L @@ -190,7 +198,23 @@ /* The barrier functions are available. */ #define _POSIX_BARRIERS 200912L +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +/* POSIX message queues are available. */ +# define _POSIX_MESSAGE_PASSING 200112L +#else /* POSIX message queues are not yet supported. */ -#undef _POSIX_MESSAGE_PASSING +# undef _POSIX_MESSAGE_PASSING +#endif + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +/* Thread process-shared synchronization is supported. */ +#define _POSIX_THREAD_PROCESS_SHARED 200112L + +/* The monotonic clock might be available. */ +#define _POSIX_MONOTONIC_CLOCK 0 + +/* The clock selection interfaces are available. */ +#define _POSIX_CLOCK_SELECTION 200112L +#endif #endif /* bits/posix_opt.h */ diff --git a/libc/sysdeps/linux/common/bits/sched.h b/libc/sysdeps/linux/common/bits/sched.h index df1d2f6da..af6276b5a 100644 --- a/libc/sysdeps/linux/common/bits/sched.h +++ b/libc/sysdeps/linux/common/bits/sched.h @@ -1,6 +1,6 @@ /* Definitions of constants and data structure for POSIX 1003.1b-1993 scheduling interface. - Copyright (C) 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc. + Copyright (C) 1996-1999,2001-2003,2005,2006 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 @@ -29,6 +29,9 @@ #define SCHED_OTHER 0 #define SCHED_FIFO 1 #define SCHED_RR 2 +#if 0 /*def __USE_GNU*/ +# define SCHED_BATCH 3 +#endif #ifdef __USE_MISC /* Cloning flags. */ diff --git a/libc/sysdeps/linux/common/bits/siginfo.h b/libc/sysdeps/linux/common/bits/siginfo.h index 03c1c11fc..4e9fd6ab4 100644 --- a/libc/sysdeps/linux/common/bits/siginfo.h +++ b/libc/sysdeps/linux/common/bits/siginfo.h @@ -301,8 +301,11 @@ enum # define SIGEV_SIGNAL SIGEV_SIGNAL SIGEV_NONE, /* Other notification: meaningless. */ # define SIGEV_NONE SIGEV_NONE - SIGEV_THREAD /* Deliver via thread creation. */ + SIGEV_THREAD, /* Deliver via thread creation. */ # define SIGEV_THREAD SIGEV_THREAD + + SIGEV_THREAD_ID = 4 /* Send signal to specific thread. */ +#define SIGEV_THREAD_ID SIGEV_THREAD_ID }; #endif /* have _SIGNAL_H. */ diff --git a/libc/sysdeps/linux/common/bits/socket.h b/libc/sysdeps/linux/common/bits/socket.h index 894cf0da2..2466c0cd1 100644 --- a/libc/sysdeps/linux/common/bits/socket.h +++ b/libc/sysdeps/linux/common/bits/socket.h @@ -264,7 +264,7 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, # define _EXTERN_INLINE extern __inline # endif _EXTERN_INLINE struct cmsghdr * -__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg) __THROW +__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg)) { if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr)) /* The kernel header does this so there may be a reason. */ diff --git a/libc/sysdeps/linux/common/bits/types.h b/libc/sysdeps/linux/common/bits/types.h index 6068f6fd2..755af2ec9 100644 --- a/libc/sysdeps/linux/common/bits/types.h +++ b/libc/sysdeps/linux/common/bits/types.h @@ -70,94 +70,136 @@ typedef struct } __u_quad_t; #endif + +/* The machine-dependent file <bits/typesizes.h> defines __*_T_TYPE + macros for each of the OS types we define below. The definitions + of those macros must use the following macros for underlying types. + We define __S<SIZE>_TYPE and __U<SIZE>_TYPE for the signed and unsigned + variants of each of the following integer types on this machine. + + 16 -- "natural" 16-bit type (always short) + 32 -- "natural" 32-bit type (always int) + 64 -- "natural" 64-bit type (long or long long) + LONG32 -- 32-bit type, traditionally long + QUAD -- 64-bit type, always long long + WORD -- natural type of __WORDSIZE bits (int or long) + LONGWORD -- type of __WORDSIZE bits, traditionally long + + We distinguish WORD/LONGWORD, 32/LONG32, and 64/QUAD so that the + conventional uses of `long' or `long long' type modifiers match the + types we define, even when a less-adorned type would be the same size. + This matters for (somewhat) portably writing printf/scanf formats for + these types, where using the appropriate l or ll format modifiers can + make the typedefs and the formats match up across all GNU platforms. If + we used `long' when it's 64 bits where `long long' is expected, then the + compiler would warn about the formats not matching the argument types, + and the programmer changing them to shut up the compiler would break the + program's portability. + + Here we assume what is presently the case in all the GCC configurations + we support: long long is always 64 bits, long is always word/address size, + and int is always 32 bits. */ + +#define __S16_TYPE short int +#define __U16_TYPE unsigned short int +#define __S32_TYPE int +#define __U32_TYPE unsigned int +#define __SLONGWORD_TYPE long int +#define __ULONGWORD_TYPE unsigned long int #if __WORDSIZE == 32 +# define __SQUAD_TYPE __quad_t +# define __UQUAD_TYPE __u_quad_t # define __SWORD_TYPE int +# define __UWORD_TYPE unsigned int +# define __SLONG32_TYPE long int +# define __ULONG32_TYPE unsigned long int +# define __S64_TYPE __quad_t +# define __U64_TYPE __u_quad_t +/* We want __extension__ before typedef's that use nonstandard base types + such as `long long' in C89 mode. */ +# define __STD_TYPE __extension__ typedef #elif __WORDSIZE == 64 +# define __SQUAD_TYPE long int +# define __UQUAD_TYPE unsigned long int # define __SWORD_TYPE long int +# define __UWORD_TYPE unsigned long int +# define __SLONG32_TYPE int +# define __ULONG32_TYPE unsigned int +# define __S64_TYPE long int +# define __U64_TYPE unsigned long int +/* No need to mark the typedef with __extension__. */ +# define __STD_TYPE typedef #else # error #endif - -typedef __u_quad_t __dev_t; /* Type of device numbers. */ -typedef __u_int __uid_t; /* Type of user identifications. */ -typedef __u_int __gid_t; /* Type of group identifications. */ -typedef __u_long __ino_t; /* Type of file serial numbers. */ -typedef __u_int __mode_t; /* Type of file attribute bitmasks. */ -typedef __u_int __nlink_t; /* Type of file link counts. */ -typedef long int __off_t; /* Type of file sizes and offsets. */ -typedef __quad_t __loff_t; /* Type of file sizes and offsets. */ -typedef int __pid_t; /* Type of process identifications. */ -typedef __SWORD_TYPE __ssize_t; /* Type of a byte count, or error. */ -typedef __u_long __rlim_t; /* Type of resource counts. */ -typedef __u_quad_t __rlim64_t; /* Type of resource counts (LFS). */ -typedef __u_int __id_t; /* General type for ID. */ - -typedef struct - { - int __val[2]; - } __fsid_t; /* Type of file system IDs. */ - -/* Everythin' else. */ -typedef int __daddr_t; /* The type of a disk address. */ -typedef __quad_t *__rqaddr_t; -typedef char *__caddr_t; -typedef long int __time_t; -typedef unsigned int __useconds_t; -typedef long int __suseconds_t; -typedef long int __swblk_t; /* Type of a swap block maybe? */ - -typedef long int __clock_t; +#include <bits/typesizes.h> /* Defines __*_T_TYPE macros. */ + + +__STD_TYPE __DEV_T_TYPE __dev_t; /* Type of device numbers. */ +__STD_TYPE __UID_T_TYPE __uid_t; /* Type of user identifications. */ +__STD_TYPE __GID_T_TYPE __gid_t; /* Type of group identifications. */ +__STD_TYPE __INO_T_TYPE __ino_t; /* Type of file serial numbers. */ +__STD_TYPE __INO64_T_TYPE __ino64_t; /* Type of file serial numbers (LFS).*/ +__STD_TYPE __MODE_T_TYPE __mode_t; /* Type of file attribute bitmasks. */ +__STD_TYPE __NLINK_T_TYPE __nlink_t; /* Type of file link counts. */ +__STD_TYPE __OFF_T_TYPE __off_t; /* Type of file sizes and offsets. */ +__STD_TYPE __OFF64_T_TYPE __off64_t; /* Type of file sizes and offsets (LFS). */ +__STD_TYPE __PID_T_TYPE __pid_t; /* Type of process identifications. */ +__STD_TYPE __FSID_T_TYPE __fsid_t; /* Type of file system IDs. */ +__STD_TYPE __CLOCK_T_TYPE __clock_t; /* Type of CPU usage counts. */ +__STD_TYPE __RLIM_T_TYPE __rlim_t; /* Type for resource measurement. */ +__STD_TYPE __RLIM64_T_TYPE __rlim64_t; /* Type for resource measurement (LFS). */ +__STD_TYPE __ID_T_TYPE __id_t; /* General type for IDs. */ +__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */ +__STD_TYPE __USECONDS_T_TYPE __useconds_t; /* Count of microseconds. */ +__STD_TYPE __SUSECONDS_T_TYPE __suseconds_t; /* Signed count of microseconds. */ + +__STD_TYPE __DADDR_T_TYPE __daddr_t; /* The type of a disk address. */ +__STD_TYPE __SWBLK_T_TYPE __swblk_t; /* Type of a swap block maybe? */ +__STD_TYPE __KEY_T_TYPE __key_t; /* Type of an IPC key. */ /* Clock ID used in clock and timer functions. */ -typedef int __clockid_t; +__STD_TYPE __CLOCKID_T_TYPE __clockid_t; /* Timer ID returned by `timer_create'. */ -typedef void *__timer_t; - - -/* Number of descriptors that can fit in an `fd_set'. */ -#define __FD_SETSIZE 1024 - - -typedef int __key_t; - -/* Used in `struct shmid_ds'. */ -typedef __kernel_ipc_pid_t __ipc_pid_t; - +__STD_TYPE __TIMER_T_TYPE __timer_t; /* Type to represent block size. */ -typedef long int __blksize_t; +__STD_TYPE __BLKSIZE_T_TYPE __blksize_t; /* Types from the Large File Support interface. */ -/* Type to count number os disk blocks. */ -typedef long int __blkcnt_t; -typedef __quad_t __blkcnt64_t; +/* Type to count number of disk blocks. */ +__STD_TYPE __BLKCNT_T_TYPE __blkcnt_t; +__STD_TYPE __BLKCNT64_T_TYPE __blkcnt64_t; /* Type to count file system blocks. */ -typedef __u_long __fsblkcnt_t; -typedef __u_quad_t __fsblkcnt64_t; - -/* Type to count file system inodes. */ -typedef __u_long __fsfilcnt_t; -typedef __u_quad_t __fsfilcnt64_t; +__STD_TYPE __FSBLKCNT_T_TYPE __fsblkcnt_t; +__STD_TYPE __FSBLKCNT64_T_TYPE __fsblkcnt64_t; -/* Type of file serial numbers. */ -typedef __u_quad_t __ino64_t; +/* Type to count file system nodes. */ +__STD_TYPE __FSFILCNT_T_TYPE __fsfilcnt_t; +__STD_TYPE __FSFILCNT64_T_TYPE __fsfilcnt64_t; -/* Type of file sizes and offsets. */ -typedef __loff_t __off64_t; +__STD_TYPE __SSIZE_T_TYPE __ssize_t; /* Type of a byte count, or error. */ -/* Used in XTI. */ -typedef long int __t_scalar_t; -typedef unsigned long int __t_uscalar_t; +/* These few don't really vary by system, they always correspond + to one of the other defined types. */ +typedef __off64_t __loff_t; /* Type of file sizes and offsets (LFS). */ +typedef __quad_t *__qaddr_t; +typedef char *__caddr_t; /* Duplicates info from stdint.h but this is used in unistd.h. */ -typedef __SWORD_TYPE __intptr_t; +__STD_TYPE __SWORD_TYPE __intptr_t; /* Duplicate info from sys/socket.h. */ -typedef unsigned int __socklen_t; +__STD_TYPE __U32_TYPE __socklen_t; + + +#undef __STD_TYPE +/* Used in `struct shmid_ds'. */ +typedef __kernel_ipc_pid_t __ipc_pid_t; /* Now add the thread types. */ #if defined __UCLIBC_HAS_THREADS__ && (defined __USE_POSIX199506 || defined __USE_UNIX98) diff --git a/libc/sysdeps/linux/common/bits/uio.h b/libc/sysdeps/linux/common/bits/uio.h index 84b4805fe..8e6bac984 100644 --- a/libc/sysdeps/linux/common/bits/uio.h +++ b/libc/sysdeps/linux/common/bits/uio.h @@ -36,6 +36,7 @@ functionality even if the currently running kernel does not support this large value the readv/writev call will not fail because of this. */ #define UIO_MAXIOV 1024 +#define UIO_FASTIOV 8 /* Structure for scatter/gather I/O. */ diff --git a/libc/sysdeps/linux/common/chown.c b/libc/sysdeps/linux/common/chown.c index 8ca955de5..d6461394b 100644 --- a/libc/sysdeps/linux/common/chown.c +++ b/libc/sysdeps/linux/common/chown.c @@ -10,6 +10,8 @@ #include "syscalls.h" #include <unistd.h> +libc_hidden_proto(chown) + #define __NR___syscall_chown __NR_chown static inline _syscall3(int, __syscall_chown, const char *, path, __kernel_uid_t, owner, __kernel_gid_t, group); @@ -23,3 +25,4 @@ int chown(const char *path, uid_t owner, gid_t group) } return (__syscall_chown(path, owner, group)); } +libc_hidden_def(chown) diff --git a/libc/sysdeps/linux/common/chroot.c b/libc/sysdeps/linux/common/chroot.c index fcf2adac2..527310a15 100644 --- a/libc/sysdeps/linux/common/chroot.c +++ b/libc/sysdeps/linux/common/chroot.c @@ -12,6 +12,7 @@ #include <string.h> #include <sys/param.h> +#if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_XOPEN2K) #define __NR___syscall_chroot __NR_chroot static inline _syscall1(int, __syscall_chroot, const char *, path); @@ -19,3 +20,4 @@ int chroot(const char *path) { return __syscall_chroot(path); } +#endif diff --git a/libc/sysdeps/linux/common/fsync.c b/libc/sysdeps/linux/common/fsync.c index 677f3e3d6..7ca709887 100644 --- a/libc/sysdeps/linux/common/fsync.c +++ b/libc/sysdeps/linux/common/fsync.c @@ -9,8 +9,27 @@ #include "syscalls.h" #include <unistd.h> +#ifdef __UCLIBC__HAS_THREADS__ +# include <sysdep-cancel.h> +#endif extern __typeof(fsync) __libc_fsync; -#define __NR___libc_fsync __NR_fsync +#ifdef __UCLIBC__HAS_THREADS__ +int __libc_fsync (int fd) +{ + if (SINGLE_THREAD_P) + return INLINE_SYSCALL (fsync, 1, fd); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = INLINE_SYSCALL (fsync, 1, fd); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +#else +# define __NR___libc_fsync __NR_fsync _syscall1(int, __libc_fsync, int, fd); +#endif weak_alias(__libc_fsync, fsync) diff --git a/libc/sysdeps/linux/common/getdnnm.c b/libc/sysdeps/linux/common/getdnnm.c index d4caec6ad..ee1b012c4 100644 --- a/libc/sysdeps/linux/common/getdnnm.c +++ b/libc/sysdeps/linux/common/getdnnm.c @@ -11,14 +11,13 @@ #include <errno.h> #include <sys/utsname.h> -libc_hidden_proto(getdomainname) - +#if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98) libc_hidden_proto(strlen) libc_hidden_proto(strcpy) libc_hidden_proto(uname) -int -getdomainname(char *name, size_t len) +libc_hidden_proto(getdomainname) +int getdomainname(char *name, size_t len) { struct utsname uts; @@ -45,3 +44,4 @@ getdomainname(char *name, size_t len) return 0; } libc_hidden_def(getdomainname) +#endif diff --git a/libc/sysdeps/linux/common/geteuid.c b/libc/sysdeps/linux/common/geteuid.c index 3936739b3..247f1bfda 100644 --- a/libc/sysdeps/linux/common/geteuid.c +++ b/libc/sysdeps/linux/common/geteuid.c @@ -2,27 +2,35 @@ /* * geteuid() for uClibc * - * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> * - * GNU Library General Public License (LGPL) version 2 or later. + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -#define getuid __getuid - #include "syscalls.h" #include <unistd.h> -#ifdef __NR_geteuid -#define __NR___syscall_geteuid __NR_geteuid +libc_hidden_proto(geteuid) + +#if defined(__NR_geteuid32) +# undef __NR_geteuid +# define __NR_geteuid __NR_geteuid32 +_syscall0(uid_t, geteuid); + +#elif defined(__NR_geteuid) +# define __NR___syscall_geteuid __NR_geteuid static inline _syscall0(int, __syscall_geteuid); -uid_t attribute_hidden __geteuid(void) +uid_t geteuid(void) { return (__syscall_geteuid()); } + #else -uid_t attribute_hidden __geteuid(void) +libc_hidden_proto(getuid) +uid_t geteuid(void) { return (getuid()); } #endif -strong_alias(__geteuid,geteuid) + +libc_hidden_def(geteuid) diff --git a/libc/sysdeps/linux/common/getpagesize.c b/libc/sysdeps/linux/common/getpagesize.c index 4a35d0775..efb5fcb7f 100644 --- a/libc/sysdeps/linux/common/getpagesize.c +++ b/libc/sysdeps/linux/common/getpagesize.c @@ -21,7 +21,6 @@ #include <sys/param.h> extern size_t __pagesize; -libc_hidden_proto(__pagesize) /* Return the system page size. */ /* couldn't make __getpagesize hidden, because shm.h uses it in a macro */ diff --git a/libc/sysdeps/linux/common/gettimeofday.c b/libc/sysdeps/linux/common/gettimeofday.c index 2d8a6cb25..8e1cf57eb 100644 --- a/libc/sysdeps/linux/common/gettimeofday.c +++ b/libc/sysdeps/linux/common/gettimeofday.c @@ -11,6 +11,9 @@ #include <sys/time.h> libc_hidden_proto(gettimeofday) - +#ifdef __USE_BSD _syscall2(int, gettimeofday, struct timeval *, tv, struct timezone *, tz); +#else +_syscall2(int, gettimeofday, struct timeval *, tv, void *, tz); +#endif libc_hidden_def(gettimeofday) diff --git a/libc/sysdeps/linux/common/getuid.c b/libc/sysdeps/linux/common/getuid.c index 7c81ccf48..21c504d65 100644 --- a/libc/sysdeps/linux/common/getuid.c +++ b/libc/sysdeps/linux/common/getuid.c @@ -2,23 +2,17 @@ /* * getuid() for uClibc * - * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> * - * GNU Library General Public License (LGPL) version 2 or later. + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ #include "syscalls.h" #include <unistd.h> -#if defined (__alpha__) -#define __NR_getuid __NR_getxuid +#if defined __NR_getxuid +# define __NR_getuid __NR_getxuid #endif -#define __NR___syscall_getuid __NR_getuid - -static inline _syscall0(int, __syscall_getuid); - -uid_t attribute_hidden __getuid(void) -{ - return (__syscall_getuid()); -} -strong_alias(__getuid,getuid) +libc_hidden_proto(getuid) +_syscall0(uid_t, getuid); +libc_hidden_def(getuid) diff --git a/libc/sysdeps/linux/common/llseek.c b/libc/sysdeps/linux/common/llseek.c index 76354fa15..0cfbe1a46 100644 --- a/libc/sysdeps/linux/common/llseek.c +++ b/libc/sysdeps/linux/common/llseek.c @@ -39,4 +39,3 @@ loff_t __libc_lseek64(int fd, loff_t offset, int whence) libc_hidden_proto(lseek64) weak_alias(__libc_lseek64,lseek64) libc_hidden_weak(lseek64) -//strong_alias(__libc_lseek64,_llseek) diff --git a/libc/sysdeps/linux/common/madvise.c b/libc/sysdeps/linux/common/madvise.c index 70ed9c4cb..8c3918060 100644 --- a/libc/sysdeps/linux/common/madvise.c +++ b/libc/sysdeps/linux/common/madvise.c @@ -9,6 +9,6 @@ #include "syscalls.h" #include <sys/mman.h> -#ifdef __NR_madvise +#if defined __NR_madvise && defined __USE_BSD _syscall3(int, madvise, void *, __addr, size_t, __len, int, __advice); #endif diff --git a/libc/sysdeps/linux/common/open64.c b/libc/sysdeps/linux/common/open64.c index f577d9507..5c19d63b5 100644 --- a/libc/sysdeps/linux/common/open64.c +++ b/libc/sysdeps/linux/common/open64.c @@ -1,35 +1,30 @@ -/* Copyright (C) 1991, 1995-1997, 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 License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ #include <features.h> #include <fcntl.h> #include <stdarg.h> +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <errno.h> +#include <sysdep-cancel.h> +#endif + +#ifdef __UCLIBC_HAS_LFS__ #ifndef O_LARGEFILE -#define O_LARGEFILE 0100000 +# define O_LARGEFILE 0100000 #endif -#ifdef __UCLIBC_HAS_LFS__ +extern __typeof(open64) __libc_open64; +extern __typeof(open) __libc_open; +libc_hidden_proto(__libc_open) + /* Open FILE with access OFLAG. If OFLAG includes O_CREAT, a third argument is the file protection. */ -#undef open64 -int attribute_hidden __open64 (const char *file, int oflag, ...) +int __libc_open64 (const char *file, int oflag, ...) { int mode = 0; @@ -41,8 +36,22 @@ int attribute_hidden __open64 (const char *file, int oflag, ...) va_end (arg); } - return __open(file, oflag | O_LARGEFILE, mode); +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ + if (SINGLE_THREAD_P) + return INLINE_SYSCALL (open, 3, file, oflag | O_LARGEFILE, mode); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = INLINE_SYSCALL (open, 3, file, oflag | O_LARGEFILE, mode); + + LIBC_CANCEL_RESET (oldtype); + + return result; +#else + return __libc_open(file, oflag | O_LARGEFILE, mode); +#endif } -strong_alias(__open64,open64) -weak_alias(__open64,__libc_open64) +libc_hidden_proto(open64) +weak_alias(__libc_open64,open64) +libc_hidden_weak(open64) #endif /* __UCLIBC_HAS_LFS__ */ diff --git a/libc/sysdeps/linux/common/poll.c b/libc/sysdeps/linux/common/poll.c index c957f1edf..61c6d18ea 100644 --- a/libc/sysdeps/linux/common/poll.c +++ b/libc/sysdeps/linux/common/poll.c @@ -17,16 +17,33 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define getdtablesize __getdtablesize -#define select __select - #include "syscalls.h" #include <sys/poll.h> +libc_hidden_proto(poll) + #ifdef __NR_poll -#define __NR___poll __NR_poll -attribute_hidden _syscall3(int, __poll, struct pollfd *, fds, +# ifdef __UCLIBC__HAS_THREADS__ +# include <sysdep-cancel.h> + +/* The real implementation. */ +int poll (struct pollfd *fds, nfsd_t nfds, int timeout) +{ + if (SINGLE_THREAD_P) + return INLINE_SYSCALL (poll, 3, fds, nfds, timeout); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = INLINE_SYSCALL (poll, 3, fds, nfds, timeout); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +# else +_syscall3(int, poll, struct pollfd *, fds, unsigned long int, nfds, int, timeout); +# endif #else #include <alloca.h> @@ -37,6 +54,11 @@ attribute_hidden _syscall3(int, __poll, struct pollfd *, fds, #include <sys/param.h> #include <unistd.h> +libc_hidden_proto(memcpy) +libc_hidden_proto(memset) +libc_hidden_proto(getdtablesize) +libc_hidden_proto(select) + /* uClinux 2.0 doesn't have poll, emulate it using select */ /* Poll the file descriptors described by the NFDS structures starting at @@ -45,7 +67,7 @@ attribute_hidden _syscall3(int, __poll, struct pollfd *, fds, Returns the number of file descriptors with events, zero if timed out, or -1 for errors. */ -int attribute_hidden __poll(struct pollfd *fds, nfds_t nfds, int timeout) +int poll(struct pollfd *fds, nfds_t nfds, int timeout) { static int max_fd_size; struct timeval tv; @@ -65,9 +87,9 @@ int attribute_hidden __poll(struct pollfd *fds, nfds_t nfds, int timeout) /* We can't call FD_ZERO, since FD_ZERO only works with sets of exactly __FD_SETSIZE size. */ - __memset (rset, 0, bytes); - __memset (wset, 0, bytes); - __memset (xset, 0, bytes); + memset (rset, 0, bytes); + memset (wset, 0, bytes); + memset (xset, 0, bytes); for (f = fds; f < &fds[nfds]; ++f) { @@ -89,13 +111,13 @@ int attribute_hidden __poll(struct pollfd *fds, nfds_t nfds, int timeout) nwset = alloca (nbytes); nxset = alloca (nbytes); - __memset ((char *) nrset + bytes, 0, nbytes - bytes); - __memset ((char *) nwset + bytes, 0, nbytes - bytes); - __memset ((char *) nxset + bytes, 0, nbytes - bytes); + memset ((char *) nrset + bytes, 0, nbytes - bytes); + memset ((char *) nwset + bytes, 0, nbytes - bytes); + memset ((char *) nxset + bytes, 0, nbytes - bytes); - rset = __memcpy (nrset, rset, bytes); - wset = __memcpy (nwset, wset, bytes); - xset = __memcpy (nxset, xset, bytes); + rset = memcpy (nrset, rset, bytes); + wset = memcpy (nwset, wset, bytes); + xset = memcpy (nxset, xset, bytes); bytes = nbytes; } @@ -129,9 +151,9 @@ int attribute_hidden __poll(struct pollfd *fds, nfds_t nfds, int timeout) struct timeval sngl_tv; /* Clear the original set. */ - __memset (rset, 0, bytes); - __memset (wset, 0, bytes); - __memset (xset, 0, bytes); + memset (rset, 0, bytes); + memset (wset, 0, bytes); + memset (xset, 0, bytes); /* This means we don't wait for input. */ sngl_tv.tv_sec = 0; @@ -148,9 +170,9 @@ int attribute_hidden __poll(struct pollfd *fds, nfds_t nfds, int timeout) { int n; - __memset (sngl_rset, 0, bytes); - __memset (sngl_wset, 0, bytes); - __memset (sngl_xset, 0, bytes); + memset (sngl_rset, 0, bytes); + memset (sngl_wset, 0, bytes); + memset (sngl_xset, 0, bytes); if (f->events & POLLIN) FD_SET (f->fd, sngl_rset); @@ -204,4 +226,4 @@ int attribute_hidden __poll(struct pollfd *fds, nfds_t nfds, int timeout) } #endif -strong_alias(__poll,poll) +libc_hidden_def(poll) diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 93a85a622..7e93537dd 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -22,6 +22,9 @@ #include <stddef.h> /* For NULL. */ #include <sys/time.h> #include <sys/select.h> +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <sysdep-cancel.h> +#endif libc_hidden_proto(sigprocmask) libc_hidden_proto(select) @@ -33,8 +36,13 @@ libc_hidden_proto(select) after waiting the interval specified therein. Additionally set the sigmask SIGMASK for this call. Returns the number of ready descriptors, or -1 for errors. */ +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +static int +__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, +#else int pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, +#endif const struct timespec *timeout, const sigset_t *sigmask) { struct timeval tval; @@ -64,3 +72,23 @@ pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, return retval; } + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +int +pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + const struct timespec *timeout, const sigset_t *sigmask) +{ + if (SINGLE_THREAD_P) + return __pselect (nfds, readfds, writefds, exceptfds, + timeout, sigmask); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = __pselect (nfds, readfds, writefds, exceptfds, + timeout, sigmask); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +#endif diff --git a/libc/sysdeps/linux/common/readv.c b/libc/sysdeps/linux/common/readv.c index 79ecf6f6d..ebe73185f 100644 --- a/libc/sysdeps/linux/common/readv.c +++ b/libc/sysdeps/linux/common/readv.c @@ -2,6 +2,7 @@ /* * readv() for uClibc * + * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com> * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> * * GNU Library General Public License (LGPL) version 2 or later. @@ -9,5 +10,41 @@ #include "syscalls.h" #include <sys/uio.h> + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <sysdep-cancel.h> + +/* We should deal with kernel which have a smaller UIO_FASTIOV as well + as a very big count. */ +static ssize_t __readv (int fd, const struct iovec *vector, int count) +{ + ssize_t bytes_read; + + bytes_read = INLINE_SYSCALL (readv, 3, fd, vector, count); + + if (bytes_read >= 0 || errno != EINVAL || count <= UIO_FASTIOV) + return bytes_read; + + /* glibc tries again, but we do not. */ + //return __atomic_readv_replacement (fd, vector, count); + + return -1; +} + +ssize_t readv (int fd, const struct iovec *vector, int count) +{ + if (SINGLE_THREAD_P) + return __readv (fd, vector, count); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = __readv (fd, vector, count); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +#else _syscall3(ssize_t, readv, int, filedes, const struct iovec *, vector, int, count); +#endif diff --git a/libc/sysdeps/linux/common/sbrk.c b/libc/sysdeps/linux/common/sbrk.c index d9a4d6899..f8b568262 100644 --- a/libc/sysdeps/linux/common/sbrk.c +++ b/libc/sysdeps/linux/common/sbrk.c @@ -13,7 +13,6 @@ libc_hidden_proto(brk) /* Defined in brk.c. */ extern void *__curbrk; -libc_hidden_proto(__curbrk) /* Extend the process's data space by INCREMENT. If INCREMENT is negative, shrink data space by - INCREMENT. diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index d5a0663fa..9a50d198a 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -8,7 +8,7 @@ */ #include "syscalls.h" -#include <unistd.h> +#include <sys/select.h> libc_hidden_proto(select) diff --git a/libc/sysdeps/linux/common/setdomainname.c b/libc/sysdeps/linux/common/setdomainname.c index 138250d09..3b9f535e5 100644 --- a/libc/sysdeps/linux/common/setdomainname.c +++ b/libc/sysdeps/linux/common/setdomainname.c @@ -9,4 +9,6 @@ #include "syscalls.h" #include <unistd.h> +#if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98) _syscall2(int, setdomainname, const char *, name, size_t, len); +#endif diff --git a/libc/sysdeps/linux/common/setegid.c b/libc/sysdeps/linux/common/setegid.c index e0bbfd4bc..33c627c51 100644 --- a/libc/sysdeps/linux/common/setegid.c +++ b/libc/sysdeps/linux/common/setegid.c @@ -11,7 +11,7 @@ #include <sys/types.h> #include <sys/syscall.h> -#if defined __NR_setresgid || defined __NR_setresgid32 +#if (defined __NR_setresgid || defined __NR_setresgid32) && defined __USE_GNU libc_hidden_proto(setresgid) #endif libc_hidden_proto(setregid) @@ -26,7 +26,7 @@ int setegid(gid_t gid) return -1; } -#if defined __NR_setresgid || defined __NR_setresgid32 +#if (defined __NR_setresgid || defined __NR_setresgid32) && defined __USE_GNU result = setresgid(-1, gid, -1); if (result == -1 && errno == ENOSYS) /* Will also set the saved group ID if egid != gid, diff --git a/libc/sysdeps/linux/common/seteuid.c b/libc/sysdeps/linux/common/seteuid.c index e5ed576ff..35a68334d 100644 --- a/libc/sysdeps/linux/common/seteuid.c +++ b/libc/sysdeps/linux/common/seteuid.c @@ -13,7 +13,7 @@ libc_hidden_proto(seteuid) -#if defined __NR_setresuid || defined __NR_setresuid32 +#if (defined __NR_setresuid || defined __NR_setresuid32) && defined __USE_GNU libc_hidden_proto(setresuid) #endif libc_hidden_proto(setreuid) @@ -28,7 +28,7 @@ int seteuid(uid_t uid) return -1; } -#if defined __NR_setresuid || defined __NR_setresuid32 +#if (defined __NR_setresuid || defined __NR_setresuid32) && defined __USE_GNU result = setresuid(-1, uid, -1); if (result == -1 && errno == ENOSYS) /* Will also set the saved user ID if euid != uid, diff --git a/libc/sysdeps/linux/common/setgroups.c b/libc/sysdeps/linux/common/setgroups.c index dd1a03f38..49f3dc61f 100644 --- a/libc/sysdeps/linux/common/setgroups.c +++ b/libc/sysdeps/linux/common/setgroups.c @@ -12,6 +12,8 @@ #include <unistd.h> #include <grp.h> +#ifdef __USE_BSD + libc_hidden_proto(setgroups) #if defined(__NR_setgroups32) @@ -62,3 +64,4 @@ ret_error: #endif libc_hidden_def(setgroups) +#endif diff --git a/libc/sysdeps/linux/common/sethostname.c b/libc/sysdeps/linux/common/sethostname.c index d8e0789bb..62867fc16 100644 --- a/libc/sysdeps/linux/common/sethostname.c +++ b/libc/sysdeps/linux/common/sethostname.c @@ -9,4 +9,6 @@ #include "syscalls.h" #include <unistd.h> +#if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98) _syscall2(int, sethostname, const char *, name, size_t, len); +#endif diff --git a/libc/sysdeps/linux/common/settimeofday.c b/libc/sysdeps/linux/common/settimeofday.c index 2dc2a6a44..a0ae95fa5 100644 --- a/libc/sysdeps/linux/common/settimeofday.c +++ b/libc/sysdeps/linux/common/settimeofday.c @@ -10,8 +10,11 @@ #include "syscalls.h" #include <sys/time.h> +#ifdef __USE_BSD + libc_hidden_proto(settimeofday) _syscall2(int, settimeofday, const struct timeval *, tv, const struct timezone *, tz); libc_hidden_def(settimeofday) +#endif diff --git a/libc/sysdeps/linux/common/sigprocmask.c b/libc/sysdeps/linux/common/sigprocmask.c index 803f5b4ae..58be06ea1 100644 --- a/libc/sysdeps/linux/common/sigprocmask.c +++ b/libc/sysdeps/linux/common/sigprocmask.c @@ -13,6 +13,8 @@ #undef sigprocmask +libc_hidden_proto(sigprocmask) + #ifdef __NR_rt_sigprocmask #define __NR___rt_sigprocmask __NR_rt_sigprocmask @@ -20,7 +22,7 @@ static inline _syscall4(int, __rt_sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset, size_t, size); -int __sigprocmask(int how, const sigset_t * set, sigset_t * oldset) +int sigprocmask(int how, const sigset_t * set, sigset_t * oldset) { #ifdef SIGCANCEL sigset_t local_newmask; @@ -55,7 +57,7 @@ static inline _syscall3(int, __syscall_sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset); -int __sigprocmask(int how, const sigset_t * set, sigset_t * oldset) +int sigprocmask(int how, const sigset_t * set, sigset_t * oldset) { #ifdef SIGCANCEL sigset_t local_newmask; @@ -82,5 +84,4 @@ int __sigprocmask(int how, const sigset_t * set, sigset_t * oldset) return (__syscall_sigprocmask(how, set, oldset)); } #endif - -weak_alias (__sigprocmask, sigprocmask) +libc_hidden_def(sigprocmask) diff --git a/libc/sysdeps/linux/common/sigsuspend.c b/libc/sysdeps/linux/common/sigsuspend.c index be69c62c2..0e0df6c61 100644 --- a/libc/sysdeps/linux/common/sigsuspend.c +++ b/libc/sysdeps/linux/common/sigsuspend.c @@ -2,31 +2,56 @@ /* * sigsuspend() for uClibc * + * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com> * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> * - * GNU Library General Public License (LGPL) version 2 or later. + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ #include "syscalls.h" #include <signal.h> #undef sigsuspend +libc_hidden_proto(sigsuspend) + #ifdef __NR_rt_sigsuspend -#define __NR___rt_sigsuspend __NR_rt_sigsuspend +# define __NR___rt_sigsuspend __NR_rt_sigsuspend + +# ifdef __UCLIBC_HAS_THREADS_NATIVE__ +# include <errno.h> +# include <sysdep-cancel.h> + +/* Change the set of blocked signals to SET, + wait until a signal arrives, and restore the set of blocked signals. */ +int sigsuspend (const sigset_t *set) +{ + if (SINGLE_THREAD_P) + return INLINE_SYSCALL (rt_sigsuspend, 2, set, _NSIG / 8); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = INLINE_SYSCALL (rt_sigsuspend, 2, set, _NSIG / 8); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +# else static inline _syscall2(int, __rt_sigsuspend, const sigset_t *, mask, size_t, size); -int attribute_hidden __sigsuspend(const sigset_t * mask) +int sigsuspend(const sigset_t * mask) { return __rt_sigsuspend(mask, _NSIG / 8); } +# endif #else -#define __NR___syscall_sigsuspend __NR_sigsuspend +# define __NR___syscall_sigsuspend __NR_sigsuspend static inline _syscall3(int, __syscall_sigsuspend, int, a, unsigned long int, b, unsigned long int, c); -int attribute_hidden __sigsuspend(const sigset_t * set) +int sigsuspend(const sigset_t * set) { return __syscall_sigsuspend(0, 0, set->__val[0]); } #endif -strong_alias(__sigsuspend,sigsuspend) +libc_hidden_def(sigsuspend) diff --git a/libc/sysdeps/linux/common/stime.c b/libc/sysdeps/linux/common/stime.c index 9f9615d3e..387122ff3 100644 --- a/libc/sysdeps/linux/common/stime.c +++ b/libc/sysdeps/linux/common/stime.c @@ -10,6 +10,8 @@ #include "syscalls.h" #include <time.h> #include <sys/time.h> + +#ifdef __USE_SVID #ifdef __NR_stime _syscall1(int, stime, const time_t *, t); #else @@ -28,3 +30,4 @@ int stime(const time_t * when) return settimeofday(&tv, (struct timezone *) 0); } #endif +#endif diff --git a/libc/sysdeps/linux/common/sysfs.c b/libc/sysdeps/linux/common/sysfs.c index 28350fdd2..e3cf0f15b 100644 --- a/libc/sysdeps/linux/common/sysfs.c +++ b/libc/sysdeps/linux/common/sysfs.c @@ -7,5 +7,10 @@ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ +/* libc isn't really supposed to export this */ +#if 0 + #include "syscalls.h" _syscall3(int, sysfs, int, option, unsigned int, index, char, addr); + +#endif diff --git a/libc/sysdeps/linux/common/umount.c b/libc/sysdeps/linux/common/umount.c index 1480b63cd..550003d1b 100644 --- a/libc/sysdeps/linux/common/umount.c +++ b/libc/sysdeps/linux/common/umount.c @@ -8,11 +8,11 @@ */ #include "syscalls.h" +#include <sys/mount.h> /* arch provides umount() syscall */ #ifdef __NR_umount -# include <sys/mount.h> _syscall1(int, umount, const char *, specialfile); /* arch provides umount2() syscall */ diff --git a/libc/sysdeps/linux/common/utime.c b/libc/sysdeps/linux/common/utime.c index 5641cc6f0..5d289aede 100644 --- a/libc/sysdeps/linux/common/utime.c +++ b/libc/sysdeps/linux/common/utime.c @@ -13,7 +13,7 @@ libc_hidden_proto(utime) #ifdef __NR_utime -attribute_hidden _syscall2(int, utime, const char *, file, const struct utimbuf *, times); +_syscall2(int, utime, const char *, file, const struct utimbuf *, times); #else #include <stdlib.h> #include <sys/time.h> diff --git a/libc/sysdeps/linux/common/vhangup.c b/libc/sysdeps/linux/common/vhangup.c index f6dc0865f..984a09dec 100644 --- a/libc/sysdeps/linux/common/vhangup.c +++ b/libc/sysdeps/linux/common/vhangup.c @@ -9,4 +9,6 @@ #include "syscalls.h" #include <unistd.h> +#if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98) _syscall0(int, vhangup); +#endif diff --git a/libc/sysdeps/linux/common/wait.c b/libc/sysdeps/linux/common/wait.c index b2a6d2295..d4b79bd37 100644 --- a/libc/sysdeps/linux/common/wait.c +++ b/libc/sysdeps/linux/common/wait.c @@ -1,5 +1,9 @@ -#define wait4 __wait4 - +/* + * Copyright (C) 2006 Steven J. Hill <sjhill@realitydiluted.com> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ #include <stdlib.h> #include <syscall.h> #include <sys/types.h> @@ -8,8 +12,32 @@ /* 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) +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <errno.h> +#include <sysdep-cancel.h> + +pid_t attribute_hidden +__libc_wait (__WAIT_STATUS_DEFN stat_loc) +{ + if (SINGLE_THREAD_P) + return INLINE_SYSCALL (wait4, 4, WAIT_ANY, stat_loc, 0, + (struct rusage *) NULL); + + int oldtype = LIBC_CANCEL_ASYNC (); + + pid_t result = INLINE_SYSCALL (wait4, 4, WAIT_ANY, stat_loc, 0, + (struct rusage *) NULL); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +#else +/* 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 __libc_wait (__WAIT_STATUS_DEFN stat_loc) { - return __wait4 (WAIT_ANY, stat_loc, 0, (struct rusage *) NULL); + return wait4 (WAIT_ANY, stat_loc, 0, (struct rusage *) NULL); } -weak_alias(wait,__libc_wait) +#endif +weak_alias(__libc_wait,wait) diff --git a/libc/sysdeps/linux/common/waitpid.c b/libc/sysdeps/linux/common/waitpid.c index 612917fcf..902a39496 100644 --- a/libc/sysdeps/linux/common/waitpid.c +++ b/libc/sysdeps/linux/common/waitpid.c @@ -1,14 +1,52 @@ -#define wait4 __wait4 +/* vi: set sw=4 ts=4: */ +/* + * Copyright (C) 2006 Steven J. Hill <sjhill@realitydiluted.com> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ #include <stdlib.h> #include <sys/types.h> -#include <sys/types.h> #include <sys/wait.h> #include <sys/resource.h> +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <errno.h> +#include <sysdep-cancel.h> +#else + +libc_hidden_proto(wait4) +#endif -__pid_t attribute_hidden __waitpid(__pid_t pid, int *wait_stat, int options) +extern __typeof(waitpid) __libc_waitpid; +__pid_t __libc_waitpid(__pid_t pid, int *wait_stat, int options) { - return __wait4(pid, wait_stat, options, NULL); +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ + if (SINGLE_THREAD_P) + { +#ifdef __NR_waitpid + return INLINE_SYSCALL (waitpid, 3, pid, wait_stat, options); +#else + return INLINE_SYSCALL (wait4, 4, pid, wait_stat, options, NULL); +#endif + } + + int oldtype = LIBC_CANCEL_ASYNC (); + +#ifdef __NR_waitpid + int result = INLINE_SYSCALL (waitpid, 3, pid, wait_stat, options); +#else + int result = INLINE_SYSCALL (wait4, 4, pid, wait_stat, options, NULL); +#endif + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +#else + return wait4(pid, wait_stat, options, NULL); } -strong_alias(__waitpid,waitpid) -weak_alias(__waitpid,__libc_waitpid) +#endif +libc_hidden_proto(waitpid) +weak_alias(__libc_waitpid,waitpid) +libc_hidden_weak(waitpid) diff --git a/libc/sysdeps/linux/common/writev.c b/libc/sysdeps/linux/common/writev.c index 4979fade9..cfb758974 100644 --- a/libc/sysdeps/linux/common/writev.c +++ b/libc/sysdeps/linux/common/writev.c @@ -2,6 +2,7 @@ /* * writev() for uClibc * + * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com> * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> * * GNU Library General Public License (LGPL) version 2 or later. @@ -9,5 +10,42 @@ #include "syscalls.h" #include <sys/uio.h> + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <errno.h> +#include <sysdep-cancel.h> + +/* We should deal with kernel which have a smaller UIO_FASTIOV as well + as a very big count. */ +static ssize_t __writev (int fd, const struct iovec *vector, int count) +{ + ssize_t bytes_written; + + bytes_written = INLINE_SYSCALL (writev, 3, fd, vector, count); + + if (bytes_written >= 0 || errno != EINVAL || count <= UIO_FASTIOV) + return bytes_written; + + /* glibc tries again, but we do not. */ + //return __atomic_writev_replacement (fd, vector, count); + + return -1; +} + +ssize_t writev (int fd, const struct iovec *vector, int count) +{ + if (SINGLE_THREAD_P) + return __writev (fd, vector, count); + + int oldtype = LIBC_CANCEL_ASYNC (); + + ssize_t result = __writev (fd, vector, count); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +#else _syscall3(ssize_t, writev, int, filedes, const struct iovec *, vector, int, count); +#endif diff --git a/libc/sysdeps/linux/mips/bits/fcntl.h b/libc/sysdeps/linux/mips/bits/fcntl.h index 1a2d40cd7..87affe3f3 100644 --- a/libc/sysdeps/linux/mips/bits/fcntl.h +++ b/libc/sysdeps/linux/mips/bits/fcntl.h @@ -1,5 +1,6 @@ /* O_*, F_*, FD_* bit values for Linux. - Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2006 + 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 @@ -21,9 +22,9 @@ # error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead." #endif +#include <sgidefs.h> #include <sys/types.h> - /* open/fcntl - O_SYNC is only implemented on blocks devices and on files located on an ext2 file system */ #define O_ACCMODE 0x0003 @@ -48,7 +49,7 @@ # define O_NOFOLLOW 0x20000 /* Do not follow links. */ # define O_DIRECT 0x8000 /* Direct disk access hint. */ # define O_DIRECTORY 0x10000 /* Must be a directory. */ -# define O_STREAMING 0x4000000/* streaming access */ +# define O_NOATIME 0x40000 /* Do not set atime. */ #endif #define O_NDELAY O_NONBLOCK @@ -81,7 +82,7 @@ #define F_SETLK64 34 /* Set record locking info (non-blocking). */ #define F_SETLKW64 35 /* Set record locking info (blocking). */ -#if defined __USE_BSD || defined __USE_XOPEN2K +#if defined __USE_BSD || defined __USE_UNIX98 # define F_SETOWN 24 /* Get owner of socket (receiver of SIGIO). */ # define F_GETOWN 23 /* Set owner of socket (receiver of SIGIO). */ #endif @@ -143,14 +144,20 @@ typedef struct flock #ifndef __USE_FILE_OFFSET64 __off_t l_start; /* Offset where the lock begins. */ __off_t l_len; /* Size of the locked area; zero means until EOF. */ - long int l_sysid; /* XXX */ +#if _MIPS_SIM != _ABI64 + /* The 64-bit flock structure, used by the n64 ABI, and for 64-bit + fcntls in o32 and n32, never has this field. */ + long int l_sysid; +#endif #else __off64_t l_start; /* Offset where the lock begins. */ __off64_t l_len; /* Size of the locked area; zero means until EOF. */ #endif __pid_t l_pid; /* Process holding the lock. */ -#ifndef __USE_FILE_OFFSET64 - long int pad[4]; /* XXX */ +#if ! defined __USE_FILE_OFFSET64 && _MIPS_SIM != _ABI64 + /* The 64-bit flock structure, used by the n64 ABI, and for 64-bit + flock in o32 and n32, never has this field. */ + long int pad[4]; #endif } flock_t; @@ -185,3 +192,17 @@ struct flock64 # define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ # define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ #endif + +/* Linux-specific operations for posix_fadvise. */ +#ifdef __USE_GNU +# define LINUX_FADV_ASYNC_WRITE 32 /* Start writeout on range. */ +# define LINUX_FADV_WRITE_WAIT 33 /* Wait upon writeout to range. */ +#endif + +__BEGIN_DECLS + +/* Provide kernel hint to read ahead. */ +extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count) + __THROW; + +__END_DECLS diff --git a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h index 317e5b389..5c8454837 100644 --- a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h +++ b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h @@ -1,3 +1,6 @@ +#ifndef _BITS_SIGACTION_STRUCT_H +#define _BITS_SIGACTION_STRUCT_H + /* This is the sigaction structure from the Linux 2.1.24 kernel. */ #include <sgidefs.h> @@ -40,4 +43,6 @@ struct kernel_sigaction { }; extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *__unbounded, - struct kernel_sigaction *__unbounded, size_t); + struct kernel_sigaction *__unbounded, size_t) attribute_hidden; + +#endif diff --git a/libc/sysdeps/linux/mips/bits/mman.h b/libc/sysdeps/linux/mips/bits/mman.h index 33f9a11df..b1b00e6f3 100644 --- a/libc/sysdeps/linux/mips/bits/mman.h +++ b/libc/sysdeps/linux/mips/bits/mman.h @@ -1,5 +1,6 @@ /* Definitions for POSIX memory map interface. Linux/MIPS version. - Copyright (C) 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1997, 2000, 2003, 2004, 2005, 2006 + 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 @@ -34,6 +35,10 @@ #define PROT_WRITE 0x2 /* Page can be written. */ #define PROT_EXEC 0x4 /* Page can be executed. */ #define PROT_NONE 0x0 /* Page can not be accessed. */ +#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of + growsdown vma (mprotect only). */ +#define PROT_GROWSUP 0x02000000 /* Extend change to start of + growsup vma (mprotect only). */ /* Sharing types (must choose one and only one of these). */ #define MAP_SHARED 0x01 /* Share changes. */ @@ -59,6 +64,8 @@ # define MAP_DENYWRITE 0x2000 /* ETXTBSY */ # define MAP_EXECUTABLE 0x4000 /* mark it as an executable */ # define MAP_LOCKED 0x8000 /* pages are locked */ +# define MAP_POPULATE 0x10000 /* populate (prefault) pagetables */ +# define MAP_NONBLOCK 0x20000 /* do not block on IO */ #endif /* Flags to `msync'. */ @@ -78,6 +85,16 @@ #define MADV_SEQUENTIAL 2 /* read-ahead aggressively */ #define MADV_WILLNEED 3 /* pre-fault pages */ #define MADV_DONTNEED 4 /* discard these pages */ +#define MADV_REMOVE 5 /* remove these pages & resources */ +#endif + +/* The POSIX people had to invent similar names for the same things. */ +#ifdef __USE_XOPEN2K +# define POSIX_MADV_NORMAL 0 /* No further special treatment. */ +# define POSIX_MADV_RANDOM 1 /* Expect random page references. */ +# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */ +# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */ +# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */ #endif /* Flags for `mremap'. */ diff --git a/libc/sysdeps/linux/mips/bits/poll.h b/libc/sysdeps/linux/mips/bits/poll.h index f62b9c394..eee4ea253 100644 --- a/libc/sysdeps/linux/mips/bits/poll.h +++ b/libc/sysdeps/linux/mips/bits/poll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2001, 2006 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 @@ -36,8 +36,10 @@ #endif #ifdef __USE_GNU -/* This is an extension for Linux. */ +/* These are extensions for Linux. */ # define POLLMSG 0x400 +# define POLLREMOVE 0x1000 +# define POLLRDHUP 0x2000 #endif /* Event types always implicitly polled for. These bits need not be set in diff --git a/libc/sysdeps/linux/mips/bits/resource.h b/libc/sysdeps/linux/mips/bits/resource.h index b8551a239..9e99f5d5d 100644 --- a/libc/sysdeps/linux/mips/bits/resource.h +++ b/libc/sysdeps/linux/mips/bits/resource.h @@ -1,5 +1,6 @@ /* Bit values & structures for resource limits. Linux/MIPS version. - Copyright (C) 1994,1996,1997,1998,1999,2000 Free Software Foundation, Inc. + Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2004, 2005, 2006 + 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 @@ -55,34 +56,54 @@ enum __rlimit_resource This affects swapping; processes that are exceeding their resident set size will be more likely to have physical memory taken from them. */ - RLIMIT_RSS = 7, -#define RLIMIT_RSS RLIMIT_RSS + __RLIMIT_RSS = 7, +#define RLIMIT_RSS __RLIMIT_RSS /* Number of open files. */ RLIMIT_NOFILE = 5, - RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */ + __RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */ #define RLIMIT_NOFILE RLIMIT_NOFILE -#define RLIMIT_OFILE RLIMIT_OFILE +#define RLIMIT_OFILE __RLIMIT_OFILE /* Address space limit (?) */ RLIMIT_AS = 6, #define RLIMIT_AS RLIMIT_AS /* Number of processes. */ - RLIMIT_NPROC = 8, -#define RLIMIT_NPROC RLIMIT_NPROC + __RLIMIT_NPROC = 8, +#define RLIMIT_NPROC __RLIMIT_NPROC /* Locked-in-memory address space. */ - RLIMIT_MEMLOCK = 9, -#define RLIMIT_MEMLOCK RLIMIT_MEMLOCK + __RLIMIT_MEMLOCK = 9, +#define RLIMIT_MEMLOCK __RLIMIT_MEMLOCK /* Maximum number of file locks. */ - RLIMIT_LOCKS = 10, -#define RLIMIT_LOCKS RLIMIT_LOCKS - - RLIM_NLIMITS = 11 -#define RLIMIT_NLIMITS RLIMIT_NLIMITS -#define RLIM_NLIMITS RLIM_NLIMITS + __RLIMIT_LOCKS = 10, +#define RLIMIT_LOCKS __RLIMIT_LOCKS + + /* Maximum number of pending signals. */ + __RLIMIT_SIGPENDING = 11, +#define RLIMIT_SIGPENDING __RLIMIT_SIGPENDING + + /* Maximum bytes in POSIX message queues. */ + __RLIMIT_MSGQUEUE = 12, +#define RLIMIT_MSGQUEUE __RLIMIT_MSGQUEUE + + /* Maximum nice priority allowed to raise to. + Nice levels 19 .. -20 correspond to 0 .. 39 + values of this resource limit. */ + __RLIMIT_NICE = 13, +#define RLIMIT_NICE __RLIMIT_NICE + + /* Maximum realtime priority allowed for non-priviledged + processes. */ + __RLIMIT_RTPRIO = 14, +#define RLIMIT_RTPRIO __RLIMIT_RTPRIO + + __RLIMIT_NLIMITS = 15, + __RLIM_NLIMITS = __RLIMIT_NLIMITS +#define RLIMIT_NLIMITS __RLIMIT_NLIMITS +#define RLIM_NLIMITS __RLIM_NLIMITS }; /* Value to indicate that there is no limit. */ @@ -137,12 +158,8 @@ enum __rusage_who #define RUSAGE_SELF RUSAGE_SELF /* All of its terminated child processes. */ - RUSAGE_CHILDREN = -1, + RUSAGE_CHILDREN = -1 #define RUSAGE_CHILDREN RUSAGE_CHILDREN - - /* Both. */ - RUSAGE_BOTH = -2 -#define RUSAGE_BOTH RUSAGE_BOTH }; #define __need_timeval diff --git a/libc/sysdeps/linux/mips/bits/siginfo.h b/libc/sysdeps/linux/mips/bits/siginfo.h index 565fa86b1..248893e86 100644 --- a/libc/sysdeps/linux/mips/bits/siginfo.h +++ b/libc/sysdeps/linux/mips/bits/siginfo.h @@ -290,10 +290,11 @@ enum # define SIGEV_SIGNAL SIGEV_SIGNAL SIGEV_NONE, /* Other notification: meaningless. */ # define SIGEV_NONE SIGEV_NONE - SIGEV_CALLBACK, /* Deliver via thread creation. */ -# define SIGEV_CALLBACK SIGEV_CALLBACK - SIGEV_THREAD /* Deliver via thread creation. */ + SIGEV_THREAD, /* Deliver via thread creation. */ # define SIGEV_THREAD SIGEV_THREAD + + SIGEV_THREAD_ID = 4 /* Send signal to specific thread. */ +#define SIGEV_THREAD_ID SIGEV_THREAD_ID }; #endif /* have _SIGNAL_H. */ diff --git a/libc/sysdeps/linux/mips/bits/syscalls.h b/libc/sysdeps/linux/mips/bits/syscalls.h index c89114401..7133d83e3 100644 --- a/libc/sysdeps/linux/mips/bits/syscalls.h +++ b/libc/sysdeps/linux/mips/bits/syscalls.h @@ -1,6 +1,5 @@ #ifndef _BITS_SYSCALLS_H #define _BITS_SYSCALLS_H - #ifndef _SYSCALL_H # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead." #endif @@ -11,15 +10,17 @@ #include <bits/sysnum.h> #ifndef __set_errno -# define __set_errno(val) (errno = (val)) +# define __set_errno(val) (*__errno_location ()) = (val) #endif - #ifndef SYS_ify -# define SYS_ify(syscall_name) __NR_##syscall_name +# define SYS_ify(syscall_name) (__NR_##syscall_name) #endif #ifndef __ASSEMBLER__ +#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \ + "$14", "$15", "$24", "$25", "memory" + #define _syscall0(type,name) \ type name(void) \ { \ @@ -265,9 +266,5 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \ return (type)-1; \ } -#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \ - "$14", "$15", "$24", "$25", "memory" - -#endif /* ! __ASSEMBLER__ */ - +#endif /* __ASSEMBLER__ */ #endif /* _BITS_SYSCALLS_H */ diff --git a/libc/sysdeps/linux/mips/brk.c b/libc/sysdeps/linux/mips/brk.c index 8d2b4ede1..cf48288f4 100644 --- a/libc/sysdeps/linux/mips/brk.c +++ b/libc/sysdeps/linux/mips/brk.c @@ -23,10 +23,7 @@ libc_hidden_proto(brk) -extern void *__curbrk; -libc_hidden_proto(__curbrk) void *__curbrk = 0; -libc_hidden_data_def(__curbrk) int brk (void *addr) { diff --git a/libc/sysdeps/linux/mips/clone.S b/libc/sysdeps/linux/mips/clone.S index 59df022c5..82f04adfa 100644 --- a/libc/sysdeps/linux/mips/clone.S +++ b/libc/sysdeps/linux/mips/clone.S @@ -96,8 +96,7 @@ NESTED(__clone,4*SZREG,sp) /* Successful return from the parent */ RESTORE_GP64 PTR_ADDU sp, FRAMESZ - j ra - nop + ret /* Something bad happened -- no child created */ L(error): @@ -118,7 +117,7 @@ L(error): its own function so that we can terminate the stack trace with our debug info. */ -LEAF(__thread_start) +ENTRY(__thread_start) L(thread_start): /* cp is already loaded. */ SAVE_GP (GPOFF) @@ -164,5 +163,4 @@ L(gotpid): END(__thread_start) -.weak clone; - clone = __clone +weak_alias (__clone, clone) diff --git a/libc/sysdeps/linux/mips/pread_write.c b/libc/sysdeps/linux/mips/pread_write.c index 5baba30d2..302dcd64f 100644 --- a/libc/sysdeps/linux/mips/pread_write.c +++ b/libc/sysdeps/linux/mips/pread_write.c @@ -1,12 +1,21 @@ /* vi: set sw=4 ts=4: * - * Copyright (C) 2002 by Erik Andersen <andersen@uclibc.org> - * Based in part on the files - * ./sysdeps/unix/sysv/linux/pwrite.c, - * ./sysdeps/unix/sysv/linux/pread.c, - * sysdeps/posix/pread.c + * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com> + * Copyright (C) 2002-2005 by Erik Andersen <andersen@uclibc.org> + * + * New version based heavily on the files: + * sysdeps/linux/sysv/linux/mips/pread.c, + * sysdeps/linux/sysv/linux/mips/pread64.c, + * sysdeps/linux/sysv/linux/mips/pwrite.c, + * sysdeps/linux/sysv/linux/mips/pwrite64.c + * from GNU libc 2.3.5, but with minor rework. + * + * Originally based in part on the files: + * sysdeps/unix/sysv/linux/pwrite.c, + * sysdeps/unix/sysv/linux/pread.c, + * sysdeps/posix/pread.c, * sysdeps/posix/pwrite.c - * from GNU libc 2.2.5, but reworked considerably... + * from GNU libc 2.2.5, but reworked considerably. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by @@ -23,7 +32,6 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define _GNU_SOURCE #define _LARGEFILE64_SOURCE #include <features.h> #undef __OPTIMIZE__ @@ -39,6 +47,10 @@ #include <sys/syscall.h> #include <unistd.h> #include <stdint.h> +#include <assert.h> +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <sysdep-cancel.h> +#endif #ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */ # ifdef __NR_pread @@ -48,30 +60,78 @@ #endif #ifdef __NR_pread +ssize_t +__libc_pread (int fd, void *buf, size_t count, off_t offset) +{ + ssize_t result; + +#if _MIPS_SIM != _ABI64 + assert (sizeof (offset) == 4); +#endif + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pread, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +#endif + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); -#ifdef __mips64 -_syscall4(ssize_t, pread, int, fd, void *, buf, size_t, count, off_t, offset); -#else /* !__mips64 */ -#define __NR___syscall_pread __NR_pread -static inline _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf, - size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo); + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pread, 4, fd, buf,, count, offset); +#else + result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +#endif + + LIBC_CANCEL_RESET (oldtype); -ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset) -{ - return(__syscall_pread(fd,buf,count,0,__LONG_LONG_PAIR(offset>>31,offset))); + return result; } weak_alias (__libc_pread, pread) #if defined __UCLIBC_HAS_LFS__ -ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset) -{ - uint32_t low = offset & 0xffffffff; - uint32_t high = offset >> 32; - return(__syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR (high, low))); +ssize_t +__libc_pread64 (int fd, void *buf, size_t count, off64_t offset) +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + return INLINE_SYSCALL (pread, 4, fd, buf, count, offset); +#else + return INLINE_SYSCALL (pread, 6, fd, buf, count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +#endif + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pread, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +#endif + + LIBC_CANCEL_RESET (oldtype); + + return result; } -weak_alias (__libc_pread64, pread64) +weak_alias(__libc_pread64, pread64) #endif /* __UCLIBC_HAS_LFS__ */ -#endif /* !__mips64 */ #endif /* __NR_pread */ @@ -85,28 +145,78 @@ weak_alias (__libc_pread64, pread64) #endif #ifdef __NR_pwrite +ssize_t +__libc_pwrite (int fd, const void *buf, size_t count, off_t offset) +{ + ssize_t result; + +#if _MIPS_SIM != _ABI64 + assert (sizeof (offset) == 4); +#endif + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +#endif + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +#endif -#ifdef __mips64 -_syscall4(ssize_t, pwrite, int, fd, const void *, buf, size_t, count, off_t, offset); -#else /* !__mips64 */ -#define __NR___syscall_pwrite __NR_pwrite -static inline _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf, - size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo); + LIBC_CANCEL_RESET (oldtype); -ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset) -{ - return(__syscall_pwrite(fd,buf,count,0,__LONG_LONG_PAIR(offset>>31,offset))); + return result; } -weak_alias (__libc_pwrite, pwrite) +weak_alias(__libc_pwrite, pwrite) #if defined __UCLIBC_HAS_LFS__ -ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset) -{ - uint32_t low = offset & 0xffffffff; - uint32_t high = offset >> 32; - return(__syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR (high, low))); +ssize_t +__libc_pwrite64 (int fd, const void *buf, size_t count, off64_t offset) +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +#endif + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +#endif + + LIBC_CANCEL_RESET (oldtype); + + return result; } -weak_alias (__libc_pwrite64, pwrite64) +weak_alias(__libc_pwrite64, pwrite64) #endif /* __UCLIBC_HAS_LFS__ */ -#endif /* !__mips64 */ + #endif /* __NR_pwrite */ diff --git a/libc/sysdeps/linux/mips/sigaction.c b/libc/sysdeps/linux/mips/sigaction.c index 085e25fe6..bd3382f63 100644 --- a/libc/sysdeps/linux/mips/sigaction.c +++ b/libc/sysdeps/linux/mips/sigaction.c @@ -1,125 +1,184 @@ -/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,1999,2000,2002,2003, 2004 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Totally hacked up for uClibc by Erik Andersen <andersen@codepoet.org> - */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include <errno.h> #include <signal.h> #include <string.h> +#include <sysdep.h> #include <sys/syscall.h> -#include <bits/kernel_sigaction.h> - -#define SA_RESTORER 0x04000000 +#include "kernel-features.h" -#if defined __NR_rt_sigaction +/* The difference here is that the sigaction structure used in the + kernel is not the same as we use in the libc. Therefore we must + translate it here. */ +#include <bits/kernel_sigaction.h> -/* 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 __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - struct kernel_sigaction kact, koact; - - if (act) { - kact.k_sa_handler = act->sa_handler; -#ifdef IS_IN_libc - __memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask)); -#else - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask)); +#ifndef LIBC_SIGACTION +extern __typeof(sigaction) __libc_sigaction; #endif - kact.sa_flags = act->sa_flags; -# ifdef HAVE_SA_RESTORER -# if _MIPS_SIM == _ABIO32 - kact.sa_restorer = act->sa_restorer; -# else - kact.sa_restorer = &restore_rt; -# endif -# endif - } - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - result = __syscall_rt_sigaction(sig, act ? __ptrvalue (&kact) : NULL, - oact ? __ptrvalue (&koact) : NULL, _NSIG / 8); - - if (oact && result >= 0) { - oact->sa_handler = koact.k_sa_handler; -#ifdef IS_IN_libc - __memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (oact->sa_mask)); -#else - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (oact->sa_mask)); +#if __ASSUME_REALTIME_SIGNALS == 0 +/* The variable is shared between all wrappers around signal handling + functions which have RT equivalents. This is the definition. */ +int __libc_missing_rt_sigs; + #endif - oact->sa_flags = koact.sa_flags; -# ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -# endif - } - return result; -} +#if _MIPS_SIM != _ABIO32 -#else -extern void restore (void) asm ("__restore") attribute_hidden; +# ifdef __NR_rt_sigreturn +static void restore_rt (void) asm ("__restore_rt"); +# endif +# ifdef __NR_sigreturn +static void restore (void) asm ("__restore"); +# endif +#endif /* 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 __libc_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 old_kernel_sigaction kact, koact; +#if __ASSUME_REALTIME_SIGNALS == 0 + struct old_kernel_sigaction k_sigact, k_osigact; +#endif + int result; - if (act) { - kact.k_sa_handler = act->sa_handler; - kact.sa_mask = act->sa_mask.__val[0]; - kact.sa_flags = act->sa_flags; +#if defined __NR_rt_sigaction || __ASSUME_REALTIME_SIGNALS > 0 + /* First try the RT signals. */ +# if __ASSUME_REALTIME_SIGNALS == 0 + if (!__libc_missing_rt_sigs) +# endif + { + struct kernel_sigaction kact, koact; + /* Save the current error value for later. We need not do this + if we are guaranteed to have realtime signals. */ +# if __ASSUME_REALTIME_SIGNALS == 0 + int saved_errno = errno; +# endif + + if (act) + { + kact.k_sa_handler = act->sa_handler; + memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kernel_sigset_t)); + kact.sa_flags = act->sa_flags; # ifdef HAVE_SA_RESTORER # if _MIPS_SIM == _ABIO32 - kact.sa_restorer = act->sa_restorer; + kact.sa_restorer = act->sa_restorer; # else - kact.sa_restorer = &restore_rt; + kact.sa_restorer = &restore_rt; # endif # endif - } + } + + /* XXX The size argument hopefully will have to be changed to the + real size of the user-level sigset_t. */ + result = INLINE_SYSCALL (rt_sigaction, 4, sig, + act ? __ptrvalue (&kact) : NULL, + oact ? __ptrvalue (&koact) : NULL, + sizeof (kernel_sigset_t)); - result = __syscall_sigaction(sig, act ? __ptrvalue (&kact) : NULL, - oact ? __ptrvalue (&koact) : NULL); +# if __ASSUME_REALTIME_SIGNALS == 0 + if (result >= 0 || errno != ENOSYS) +# endif + { + if (oact && result >= 0) + { + oact->sa_handler = koact.k_sa_handler; + memcpy (&oact->sa_mask, &koact.sa_mask, + sizeof (kernel_sigset_t)); + oact->sa_flags = koact.sa_flags; +# ifdef HAVE_SA_RESTORER + oact->sa_restorer = koact.sa_restorer; +# endif + } + return result; + } - if (result < 0) { - __set_errno(-result); - return -1; +# if __ASSUME_REALTIME_SIGNALS == 0 + __set_errno (saved_errno); + __libc_missing_rt_sigs = 1; +# endif } +#endif - if (oact) { - oact->sa_handler = koact.k_sa_handler; - oact->sa_mask.__val[0] = koact.sa_mask; - oact->sa_flags = koact.sa_flags; +#if __ASSUME_REALTIME_SIGNALS == 0 + if (act) + { + k_sigact.k_sa_handler = act->sa_handler; + k_sigact.sa_mask = act->sa_mask.__val[0]; + k_sigact.sa_flags = act->sa_flags; # ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; + k_sigact.sa_restorer = act->sa_restorer; # endif } - return result; -} - + result = INLINE_SYSCALL (sigaction, 3, sig, + act ? __ptrvalue (&k_sigact) : NULL, + oact ? __ptrvalue (&k_osigact) : NULL); + if (oact && result >= 0) + { + oact->sa_handler = k_osigact.k_sa_handler; + oact->sa_mask.__val[0] = k_osigact.sa_mask; + oact->sa_flags = k_osigact.sa_flags; +# ifdef HAVE_SA_RESTORER +# if _MIPS_SIM == _ABIO32 + oact->sa_restorer = k_osigact.sa_restorer; +# else + oact->sa_restorer = &restore; +# endif +# endif + } + return result; #endif +} #ifndef LIBC_SIGACTION -hidden_weak_alias(__libc_sigaction,__sigaction) +libc_hidden_proto(sigaction) weak_alias(__libc_sigaction,sigaction) +libc_hidden_weak(sigaction) +#endif + +/* NOTE: Please think twice before making any changes to the bits of + code below. GDB needs some intimate knowledge about it to + recognize them as signal trampolines, and make backtraces through + signal handlers work right. Important are both the names + (__restore_rt) and the exact instruction sequence. + If you ever feel the need to make any changes, please notify the + appropriate GDB maintainer. */ + +#define RESTORE(name, syscall) RESTORE2 (name, syscall) +#define RESTORE2(name, syscall) \ +asm \ + ( \ + ".align 4\n" \ + "__" #name ":\n" \ + " li $2, " #syscall "\n" \ + " syscall\n" \ + ); + +/* The return code for realtime-signals. */ +#if _MIPS_SIM != _ABIO32 +# ifdef __NR_rt_sigreturn +RESTORE (restore_rt, __NR_rt_sigreturn) +# endif +# ifdef __NR_sigreturn +RESTORE (restore, __NR_sigreturn) +# endif #endif |