From 053cc7bbc8ff66ab81f3e1d3ed89900785acd06f Mon Sep 17 00:00:00 2001 From: Geoff Keating Date: Thu, 27 Jan 2000 23:40:48 +0000 Subject: * csu/Makefile ($(objpfx)version-info.h): Don't use echo -n unnecessarily. * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_STAT64_SYSCALL, __ASSUME_TRUNCATE64_SYSCALL, __ASSUME_NEW_GETRLIMIT_SYSCALL): Define on powerpc for kernels >= 2.3.35. * sysdeps/unix/sysv/linux/powerpc/bits/resource.h: New file. * sysdeps/unix/sysv/linux/powerpc/ftruncate64.c: New file. * sysdeps/unix/sysv/linux/powerpc/getrlimit.c: New file. * sysdeps/unix/sysv/linux/powerpc/getrlimit64.c: New file. * sysdeps/unix/sysv/linux/powerpc/mmap64.c: New file. * sysdeps/unix/sysv/linux/powerpc/setrlimit.c: New file. * sysdeps/unix/sysv/linux/powerpc/setrlimit64.c: New file. * sysdeps/unix/sysv/linux/powerpc/syscalls.list: Add s_fstat64, s_ftruncate64, s_lstat64, s_mmap2, s_stat64, s_truncate64. * sysdeps/unix/sysv/linux/powerpc/truncate64.c: New file. * sysdeps/unix/sysv/linux/powerpc/Versions: New file. * sysdeps/unix/sysv/linux/powerpc/brk.S [!PIC]: Don't access __curbrk off the small data area register. Reported by Andrew Haley . 2000-01-27 Geoff Keating * csu/Makefile ($(objpfx)version-info.h): Don't use echo -n unnecessarily. * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_STAT64_SYSCALL, __ASSUME_TRUNCATE64_SYSCALL, __ASSUME_NEW_GETRLIMIT_SYSCALL): Define on powerpc for kernels >= 2.3.35. * sysdeps/unix/sysv/linux/powerpc/bits/resource.h: New file. * sysdeps/unix/sysv/linux/powerpc/ftruncate64.c: New file. * sysdeps/unix/sysv/linux/powerpc/getrlimit.c: New file. * sysdeps/unix/sysv/linux/powerpc/getrlimit64.c: New file. * sysdeps/unix/sysv/linux/powerpc/mmap64.c: New file. * sysdeps/unix/sysv/linux/powerpc/setrlimit.c: New file. * sysdeps/unix/sysv/linux/powerpc/setrlimit64.c: New file. * sysdeps/unix/sysv/linux/powerpc/syscalls.list: Add s_fstat64, s_ftruncate64, s_lstat64, s_mmap2, s_stat64, s_truncate64. * sysdeps/unix/sysv/linux/powerpc/truncate64.c: New file. * sysdeps/unix/sysv/linux/powerpc/Versions: New file. * sysdeps/unix/sysv/linux/powerpc/brk.S [!PIC]: Don't access __curbrk off the small data area register. Reported by Andrew Haley . --- sysdeps/unix/sysv/linux/kernel-features.h | 7 + sysdeps/unix/sysv/linux/powerpc/Versions | 6 + sysdeps/unix/sysv/linux/powerpc/bits/resource.h | 205 ++++++++++++++++++++++++ sysdeps/unix/sysv/linux/powerpc/brk.S | 5 +- sysdeps/unix/sysv/linux/powerpc/ftruncate64.c | 76 +++++++++ sysdeps/unix/sysv/linux/powerpc/getrlimit.c | 1 + sysdeps/unix/sysv/linux/powerpc/getrlimit64.c | 1 + sysdeps/unix/sysv/linux/powerpc/mmap64.c | 76 +++++++++ sysdeps/unix/sysv/linux/powerpc/setrlimit.c | 1 + sysdeps/unix/sysv/linux/powerpc/setrlimit64.c | 1 + sysdeps/unix/sysv/linux/powerpc/syscalls.list | 6 + sysdeps/unix/sysv/linux/powerpc/truncate64.c | 76 +++++++++ 12 files changed, 459 insertions(+), 2 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/powerpc/Versions create mode 100644 sysdeps/unix/sysv/linux/powerpc/bits/resource.h create mode 100644 sysdeps/unix/sysv/linux/powerpc/ftruncate64.c create mode 100644 sysdeps/unix/sysv/linux/powerpc/getrlimit.c create mode 100644 sysdeps/unix/sysv/linux/powerpc/getrlimit64.c create mode 100644 sysdeps/unix/sysv/linux/powerpc/mmap64.c create mode 100644 sysdeps/unix/sysv/linux/powerpc/setrlimit.c create mode 100644 sysdeps/unix/sysv/linux/powerpc/setrlimit64.c create mode 100644 sysdeps/unix/sysv/linux/powerpc/truncate64.c (limited to 'sysdeps/unix') diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 626b116242..b799a33cb9 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -103,6 +103,13 @@ # define __ASSUME_STAT64_SYSCALL 1 #endif +/* I know for sure that these are in 2.3.35 on powerpc. */ +#if __LINUX_KERNEL_VERSION >= 131875 && defined __powerpc__ +# define __ASSUME_TRUNCATE64_SYSCALL 1 +# define __ASSUME_STAT64_SYSCALL 1 +# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1 +#endif + /* Linux 2.3.39 introduced 32bit UID/GIDs. */ #if __LINUX_KERNEL_VERSION >= 131879 # define __ASSUME_32BITUIDS 1 diff --git a/sysdeps/unix/sysv/linux/powerpc/Versions b/sysdeps/unix/sysv/linux/powerpc/Versions new file mode 100644 index 0000000000..80df088a0c --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/Versions @@ -0,0 +1,6 @@ +libc { + GLIBC_2.2 { + # New rlimit interface + getrlimit; setrlimit; getrlimit64; setrlimit64; + } +} diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/resource.h b/sysdeps/unix/sysv/linux/powerpc/bits/resource.h new file mode 100644 index 0000000000..d78dd584e2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/bits/resource.h @@ -0,0 +1,205 @@ +/* Bit values & structures for resource limits. Linux version. + Copyright (C) 1994-99, 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 Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library 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. */ + +#ifndef _SYS_RESOURCE_H +# error "Never use directly; include instead." +#endif + +#include + +/* Transmute defines to enumerations. The macro re-definitions are + necessary because some programs want to test for operating system + features with #ifdef RUSAGE_SELF. In ISO C the reflexive + definition is a no-op. */ + +/* Kinds of resource limit. */ +enum __rlimit_resource +{ + /* Per-process CPU limit, in seconds. */ + RLIMIT_CPU = 0, +#define RLIMIT_CPU RLIMIT_CPU + + /* Largest file that can be created, in bytes. */ + RLIMIT_FSIZE = 1, +#define RLIMIT_FSIZE RLIMIT_FSIZE + + /* Maximum size of data segment, in bytes. */ + RLIMIT_DATA = 2, +#define RLIMIT_DATA RLIMIT_DATA + + /* Maximum size of stack segment, in bytes. */ + RLIMIT_STACK = 3, +#define RLIMIT_STACK RLIMIT_STACK + + /* Largest core file that can be created, in bytes. */ + RLIMIT_CORE = 4, +#define RLIMIT_CORE RLIMIT_CORE + + /* Largest resident set size, in bytes. + This affects swapping; processes that are exceeding their + resident set size will be more likely to have physical memory + taken from them. */ + RLIMIT_RSS = 5, +#define RLIMIT_RSS RLIMIT_RSS + + /* Number of open files. */ + RLIMIT_NOFILE = 7, + RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */ +#define RLIMIT_NOFILE RLIMIT_NOFILE +#define RLIMIT_OFILE RLIMIT_OFILE + + /* Address space limit. */ + RLIMIT_AS = 9, +#define RLIMIT_AS RLIMIT_AS + + /* Number of processes. */ + RLIMIT_NPROC = 6, +#define RLIMIT_NPROC RLIMIT_NPROC + + /* Locked-in-memory address space. */ + RLIMIT_MEMLOCK = 8, +#define RLIMIT_MEMLOCK RLIMIT_MEMLOCK + + RLIMIT_NLIMITS = 10, + RLIM_NLIMITS = RLIMIT_NLIMITS +#define RLIMIT_NLIMITS RLIMIT_NLIMITS +#define RLIM_NLIMITS RLIM_NLIMITS +}; + +/* Value to indicate that there is no limit. */ +#ifndef __USE_FILE_OFFSET64 +# define RLIM_INFINITY ((unsigned long int)(~0UL)) +#else +# define RLIM_INFINITY 0xffffffffffffffffuLL +#endif + +#ifdef __USE_LARGEFILE64 +# define RLIM64_INFINITY 0xffffffffffffffffuLL +#endif + +/* We can represent all limits. */ +#define RLIM_SAVED_MAX RLIM_INFINITY +#define RLIM_SAVED_CUR RLIM_INFINITY + + +/* Type for resource quantity measurement. */ +#ifndef __USE_FILE_OFFSET64 +typedef __rlim_t rlim_t; +#else +typedef __rlim64_t rlim_t; +#endif +#ifdef __USE_LARGEFILE64 +typedef __rlim64_t rlim64_t; +#endif + +struct rlimit + { + /* The current (soft) limit. */ + rlim_t rlim_cur; + /* The hard limit. */ + rlim_t rlim_max; + }; + +#ifdef __USE_LARGEFILE64 +struct rlimit64 + { + /* The current (soft) limit. */ + rlim64_t rlim_cur; + /* The hard limit. */ + rlim64_t rlim_max; + }; +#endif + +/* Whose usage statistics do you want? */ +enum __rusage_who +{ + /* The calling process. */ + RUSAGE_SELF = 0, +#define RUSAGE_SELF RUSAGE_SELF + + /* All of its terminated child processes. */ + RUSAGE_CHILDREN = -1, +#define RUSAGE_CHILDREN RUSAGE_CHILDREN + + /* Both. */ + RUSAGE_BOTH = -2 +#define RUSAGE_BOTH RUSAGE_BOTH +}; + +#define __need_timeval +#include /* For `struct timeval'. */ + +/* Structure which says how much of each resource has been used. */ +struct rusage + { + /* Total amount of user time used. */ + struct timeval ru_utime; + /* Total amount of system time used. */ + struct timeval ru_stime; + /* Maximum resident set size (in kilobytes). */ + long int ru_maxrss; + /* Amount of sharing of text segment memory + with other processes (kilobyte-seconds). */ + long int ru_ixrss; + /* Amount of data segment memory used (kilobyte-seconds). */ + long int ru_idrss; + /* Amount of stack memory used (kilobyte-seconds). */ + long int ru_isrss; + /* Number of soft page faults (i.e. those serviced by reclaiming + a page from the list of pages awaiting reallocation. */ + long int ru_minflt; + /* Number of hard page faults (i.e. those that required I/O). */ + long int ru_majflt; + /* Number of times a process was swapped out of physical memory. */ + long int ru_nswap; + /* Number of input operations via the file system. Note: This + and `ru_oublock' do not include operations with the cache. */ + long int ru_inblock; + /* Number of output operations via the file system. */ + long int ru_oublock; + /* Number of IPC messages sent. */ + long int ru_msgsnd; + /* Number of IPC messages received. */ + long int ru_msgrcv; + /* Number of signals delivered. */ + long int ru_nsignals; + /* Number of voluntary context switches, i.e. because the process + gave up the process before it had to (usually to wait for some + resource to be available). */ + long int ru_nvcsw; + /* Number of involuntary context switches, i.e. a higher priority process + became runnable or the current process used up its time slice. */ + long int ru_nivcsw; + }; + +/* Priority limits. */ +#define PRIO_MIN -20 /* Minimum priority a process can have. */ +#define PRIO_MAX 20 /* Maximum priority a process can have. */ + +/* The type of the WHICH argument to `getpriority' and `setpriority', + indicating what flavor of entity the WHO argument specifies. */ +enum __priority_which +{ + PRIO_PROCESS = 0, /* WHO is a process ID. */ +#define PRIO_PROCESS PRIO_PROCESS + PRIO_PGRP = 1, /* WHO is a process group ID. */ +#define PRIO_PGRP PRIO_PGRP + PRIO_USER = 2 /* WHO is a user ID. */ +#define PRIO_USER PRIO_USER +}; diff --git a/sysdeps/unix/sysv/linux/powerpc/brk.S b/sysdeps/unix/sysv/linux/powerpc/brk.S index 16f5215fd4..3147bafaee 100644 --- a/sysdeps/unix/sysv/linux/powerpc/brk.S +++ b/sysdeps/unix/sysv/linux/powerpc/brk.S @@ -1,5 +1,5 @@ /* brk system call for Linux/ppc. - Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 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 @@ -36,7 +36,8 @@ ENTRY(__brk) mtlr r4 stw r3,0(r5) #else - stw r3,__curbrk@sdarel(r13) + lis r4,__curbrk@ha + stw r3,__curbrk@sdarel(r4) #endif cmplw r6,r3 addi r1,r1,16 diff --git a/sysdeps/unix/sysv/linux/powerpc/ftruncate64.c b/sysdeps/unix/sysv/linux/powerpc/ftruncate64.c new file mode 100644 index 0000000000..379f727f08 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/ftruncate64.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library 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. */ + +#include +#include +#include + +#include +#include + +#include "kernel-features.h" + +#ifdef __NR_ftruncate64 +#ifndef __ASSUME_TRUNCATE64_SYSCALL +/* The variable is shared between all wrappers around *truncate64 calls. */ +extern int have_no_truncate64; +#endif + +extern int __syscall_ftruncate64 (int fd, off64_t length); + + +/* Truncate the file FD refers to to LENGTH bytes. */ +int +ftruncate64 (fd, length) + int fd; + off64_t length; +{ +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (! have_no_truncate64) +#endif + { +#ifndef __ASSUME_TRUNCATE64_SYSCALL + int saved_errno = errno; +#endif + int result = __syscall_ftruncate64 (fd, off64_length); + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (result != -1 || errno != ENOSYS) +#endif + return result; + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + __set_errno (saved_errno); + have_no_truncate64 = 1; +#endif + } + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if ((off_t) length != length) + { + __set_errno (EINVAL); + return -1; + } + return __ftruncate (fd, (off_t) length); +#endif +} + +#else +/* Use the generic implementation. */ +# include +#endif diff --git a/sysdeps/unix/sysv/linux/powerpc/getrlimit.c b/sysdeps/unix/sysv/linux/powerpc/getrlimit.c new file mode 100644 index 0000000000..fc06dbd641 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/getrlimit.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/powerpc/getrlimit64.c b/sysdeps/unix/sysv/linux/powerpc/getrlimit64.c new file mode 100644 index 0000000000..fef018f471 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/getrlimit64.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/powerpc/mmap64.c b/sysdeps/unix/sysv/linux/powerpc/mmap64.c new file mode 100644 index 0000000000..135ed99a36 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/mmap64.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 1999. + + 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. + + 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. + + 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. */ + +#include +#include + +#include +#include + +#include + +#include + +#include "kernel-features.h" + +#ifdef __NR_mmap2 +extern int __syscall_mmap2(__ptr_t, size_t, int, int, int, off_t); +#ifndef __ASSUME_MMAP2_SYSCALL +static int have_no_mmap2; +#endif +#endif + +__ptr_t +__mmap64 (__ptr_t addr, size_t len, int prot, int flags, int fd, off64_t offset) +{ +#ifdef __NR_mmap2 + if ( +#ifndef __ASSUME_MMAP2_SYSCALL + ! have_no_mmap2 && +#endif + ! (offset & PAGE_MASK)) + { +#ifndef __ASSUME_MMAP2_SYSCALL + int saved_errno = errno; +#endif + /* This will be always 12, no matter what page size is. */ + int result = INLINE_SYSCALL (mmap2, 6, addr, len, prot, flags, + fd, (off_t) (offset >> PAGE_SHIFT)); + +#ifndef __ASSUME_MMAP2_SYSCALL + if (result != -1 || errno != ENOSYS) +#endif + return result; + +#ifndef __ASSUME_MMAP2_SYSCALL + __set_errno (saved_errno); + have_no_mmap2 = 1; +#endif + } +#endif + if (offset != (off_t) offset || (offset + len) != (off_t) (offset + len)) + { + __set_errno (EINVAL); + return MAP_FAILED; + } + + return __mmap (addr, len, prot, flags, fd, (off_t) offset); +} + +weak_alias (__mmap64, mmap64) diff --git a/sysdeps/unix/sysv/linux/powerpc/setrlimit.c b/sysdeps/unix/sysv/linux/powerpc/setrlimit.c new file mode 100644 index 0000000000..bfaef74c38 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/setrlimit.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/powerpc/setrlimit64.c b/sysdeps/unix/sysv/linux/powerpc/setrlimit64.c new file mode 100644 index 0000000000..ed64b871f4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/setrlimit64.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/powerpc/syscalls.list b/sysdeps/unix/sysv/linux/powerpc/syscalls.list index abe89ed616..d6fdd4cc6c 100644 --- a/sysdeps/unix/sysv/linux/powerpc/syscalls.list +++ b/sysdeps/unix/sysv/linux/powerpc/syscalls.list @@ -12,6 +12,8 @@ rt_sigprocmask - rt_sigprocmask 4 __syscall_rt_sigprocmask rt_sigqueueinfo - rt_sigqueueinfo 3 __syscall_rt_sigqueueinfo rt_sigsuspend - rt_sigsuspend 2 __syscall_rt_sigsuspend rt_sigtimedwait - rt_sigtimedwait 4 __syscall_rt_sigtimedwait +s_fstat64 fxstat64 fstat64 2 __syscall_fstat64 +s_ftruncate64 ftruncate64 ftruncate64 3 __syscall_ftruncate64 s_getcwd getcwd getcwd 2 __syscall_getcwd s_getdents getdents getdents 3 __syscall_getdents s_getpmsg getpmsg getpmsg 5 __syscall_getpmsg @@ -19,6 +21,8 @@ s_getpriority getpriority getpriority 2 __syscall_getpriority s_getresgid getresgid getresgid 3 __syscall_getresgid s_getresuid getresuid getresuid 3 __syscall_getresuid s_getrlimit getrlimit getrlimit 2 __syscall_getrlimit +s_lstat64 lxstat64 lstat64 2 __syscall_lstat64 +s_mmap2 mmap64 mmap2 6 __syscall_mmap2 s_poll poll poll 3 __syscall_poll s_pread64 pread64 pread 5 __syscall_pread s_ptrace ptrace ptrace 4 __syscall_ptrace @@ -30,7 +34,9 @@ s_sigaction sigaction sigaction 3 __syscall_sigaction s_sigpending sigpending sigpending 1 __syscall_sigpending s_sigprocmask sigprocmask sigprocmask 3 __syscall_sigprocmask s_sigsuspend sigsuspend sigsuspend 3 __syscall_sigsuspend +s_stat64 xstat64 stat64 2 __syscall_stat64 s_sysctl sysctl _sysctl 1 __syscall__sysctl +s_truncate64 truncate64 truncate64 3 __syscall_truncate64 s_ugetrlimit getrlimit ugetrlimit 2 __syscall_ugetrlimit s_ustat ustat ustat 2 __syscall_ustat s_vfork vfork vfork 0 __syscall_vfork diff --git a/sysdeps/unix/sysv/linux/powerpc/truncate64.c b/sysdeps/unix/sysv/linux/powerpc/truncate64.c new file mode 100644 index 0000000000..eeea7c44fd --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/truncate64.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library 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. */ + +#include +#include +#include + +#include +#include + +#include "kernel-features.h" + +#ifdef __NR_truncate64 +#ifndef __ASSUME_TRUNCATE64_SYSCALL +/* The variable is shared between all wrappers around *truncate64 calls. */ +int have_no_truncate64; +#endif + +extern int __syscall_truncate64 (const char *path, off64_t length); + + +/* Truncate the file FD refers to to LENGTH bytes. */ +int +truncate64 (path, length) + const char *path; + off64_t length; +{ +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (! have_no_truncate64) +#endif + { +#ifndef __ASSUME_TRUNCATE64_SYSCALL + int saved_errno = errno; +#endif + int result = __syscall_truncate64 (path, length); + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (result != -1 || errno != ENOSYS) +#endif + return result; + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + __set_errno (saved_errno); + have_no_truncate64 = 1; +#endif + } + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if ((off_t) length != length) + { + __set_errno (EINVAL); + return -1; + } + return truncate (path, (off_t) length); +#endif +} + +#else +/* Use the generic implementation. */ +# include +#endif -- cgit 1.4.1