diff options
Diffstat (limited to 'libc/sysdeps/linux/mips')
| -rw-r--r-- | libc/sysdeps/linux/mips/bits/fcntl.h | 35 | ||||
| -rw-r--r-- | libc/sysdeps/linux/mips/bits/kernel_sigaction.h | 7 | ||||
| -rw-r--r-- | libc/sysdeps/linux/mips/bits/mman.h | 19 | ||||
| -rw-r--r-- | libc/sysdeps/linux/mips/bits/poll.h | 6 | ||||
| -rw-r--r-- | libc/sysdeps/linux/mips/bits/resource.h | 57 | ||||
| -rw-r--r-- | libc/sysdeps/linux/mips/bits/siginfo.h | 7 | ||||
| -rw-r--r-- | libc/sysdeps/linux/mips/bits/syscalls.h | 15 | ||||
| -rw-r--r-- | libc/sysdeps/linux/mips/brk.c | 3 | ||||
| -rw-r--r-- | libc/sysdeps/linux/mips/clone.S | 8 | ||||
| -rw-r--r-- | libc/sysdeps/linux/mips/pread_write.c | 190 | ||||
| -rw-r--r-- | libc/sysdeps/linux/mips/sigaction.c | 223 |
11 files changed, 397 insertions, 173 deletions
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 |
