This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: pread64/pwrite64 cleanup


>>>>> Ralf Baechle writes:

Ralf> No, this must be an missunderstanding.  Basically the problem is that a
Ralf> 64-bit argument has to be split into two 32-bit arguments for the
Ralf> 32-bit ABI.  Such a pair of arguments has to be passed in an aligned
Ralf> pair of arguments, that is argumnts 0/1, 2/3, 4/5 etc. but not 1/2 etc.
Ralf> If necessary fill arguments have to be used.

Thanks for the explanation.  I've added the files now.

Andreas

2000-05-30  Andreas Jaeger  <aj@suse.de>

        * sysdeps/unix/sysv/linux/mips/truncate64.c: New file.
        * sysdeps/unix/sysv/linux/mips/ftruncate64.c: New file.
        * sysdeps/unix/sysv/linux/mips/pread64.c: Readded file.
        * sysdeps/unix/sysv/linux/mips/pwrite64.c: Readded file.
        * sysdeps/unix/sysv/linux/mips/pread.c: Readded file.
        * sysdeps/unix/sysv/linux/mips/pwrite.c: Readded file.



============================================================
Index: sysdeps/unix/sysv/linux/mips/truncate64.c
--- sysdeps/unix/sysv/linux/mips/truncate64.c	created
+++ sysdeps/unix/sysv/linux/mips/truncate64.c	Tue May 30 14:50:17 2000	1.1
@@ -0,0 +1,84 @@
+/* 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 <sys/types.h>
+#include <endian.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#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
+
+/* The order of hight, low depends on endianness.  */
+extern int __syscall_truncate64 (const char *path, int high_length, int low_length);
+
+
+/* Truncate the file FD refers to to LENGTH bytes.  */
+int
+truncate64 (const char *path, off64_t length)
+{
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+  if (! __have_no_truncate64)
+#endif
+    {
+      unsigned int low = length & 0xffffffff;
+      unsigned int high = length >> 32;
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+      int saved_errno = errno;
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+      /* Use a fill argument to pass low, high in an aligned pair of
+         arguments (here 2/3).  */
+      int result = INLINE_SYSCALL (truncate64, 3, path, 0, low, high);
+#elif __BYTE_ORDER == __BIG_ENDIAN
+      int result = INLINE_SYSCALL (truncate64, 3, path, 0, high, low);
+#endif
+
+#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 <sysdeps/generic/truncate64.c>
+#endif
============================================================
Index: sysdeps/unix/sysv/linux/mips/ftruncate64.c
--- sysdeps/unix/sysv/linux/mips/ftruncate64.c	created
+++ sysdeps/unix/sysv/linux/mips/ftruncate64.c	Tue May 30 14:50:17 2000	1.1
@@ -0,0 +1,83 @@
+/* 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 <sys/types.h>
+#include <errno.h>
+#include <endian.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#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
+
+/* The order of hight, low depends on endianness.  */
+extern int __syscall_ftruncate64 (int fd, int high_length, int low_length);
+
+
+/* Truncate the file FD refers to to LENGTH bytes.  */
+int
+ftruncate64 (int fd, off64_t length)
+{
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+  if (! __have_no_truncate64)
+#endif
+    {
+      unsigned int low = length & 0xffffffff;
+      unsigned int high = length >> 32;
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+      int saved_errno = errno;
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+      /* Use a fill argument to pass low, high in an aligned pair of
+         arguments (here 2/3).  */
+      int result = INLINE_SYSCALL (ftruncate64, 3, fd, 0, low, high);
+#elif __BYTE_ORDER == __BIG_ENDIAN
+      int result = INLINE_SYSCALL (ftruncate64, 3, fd, 0, high, low);
+#endif
+#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 <sysdeps/generic/ftruncate64.c>
+#endif
============================================================
Index: sysdeps/unix/sysv/linux/mips/pread64.c
--- sysdeps/unix/sysv/linux/mips/pread64.c	created
+++ sysdeps/unix/sysv/linux/mips/pread64.c	Tue May 30 19:59:16 2000	1.1
@@ -0,0 +1,75 @@
+/* Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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 <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
+static ssize_t __emulate_pread64 (int fd, void *buf, size_t count,
+				  off64_t offset) internal_function;
+# endif
+
+extern ssize_t __syscall_pread (int fd, void *buf, size_t count, int dummy,
+			        off_t offset_hi, off_t offset_lo);
+
+
+
+ssize_t
+__libc_pread64 (fd, buf, count, offset)
+     int fd;
+     void *buf;
+     size_t count;
+     off64_t offset;
+{
+  ssize_t result;
+
+  /* First try the syscall.  */
+# if defined(__MIPSEB__)
+  result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0, (off_t) (offset >> 32),
+			   (off_t) (offset & 0xffffffff));
+# elif defined(__MIPSEL__)
+  result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0,
+			   (off_t) (offset & 0xffffffff),
+			   (off_t) (offset >> 32));
+# endif
+# if __ASSUME_PREAD_SYSCALL == 0
+  if (result == -1 && errno == ENOSYS)
+    /* No system call available.  Use the emulation.  */
+    result = __emulate_pread64 (fd, buf, count, offset);
+# endif
+  return result;
+}
+
+weak_alias (__libc_pread64, __pread64)
+weak_alias (__libc_pread64, pread64)
+
+# define __libc_pread64(fd, buf, count, offset) \
+     static internal_function __emulate_pread64 (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread64.c>
+#endif
============================================================
Index: sysdeps/unix/sysv/linux/mips/pwrite64.c
--- sysdeps/unix/sysv/linux/mips/pwrite64.c	created
+++ sysdeps/unix/sysv/linux/mips/pwrite64.c	Tue May 30 19:59:16 2000	1.1
@@ -0,0 +1,75 @@
+/* Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ralf Baechle <ralf@gnu.org>, 1998.
+
+   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 <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+extern ssize_t __syscall_pwrite (int fd, const void *buf, size_t count,
+				 int dummy, off_t offset_hi, off_t offset_lo);
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count,
+				   off64_t offset) internal_function;
+# endif
+
+ssize_t
+__libc_pwrite64 (fd, buf, count, offset)
+     int fd;
+     const void *buf;
+     size_t count;
+     off64_t offset;
+{
+  ssize_t result;
+
+  /* First try the syscall.  */
+# if defined(__MIPSEB__)
+  result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, (off_t) (offset >> 32),
+			   (off_t) (offset & 0xffffffff));
+# elif defined(__MIPSEL__)
+  result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0,
+			   (off_t) (offset & 0xffffffff),
+			   (off_t) (offset >> 32));
+# endif
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+  if (result == -1 && errno == ENOSYS)
+    /* No system call available.  Use the emulation.  */
+    result = __emulate_pwrite64 (fd, buf, count, offset);
+# endif
+
+  return result;
+}
+
+weak_alias (__libc_pwrite64, __pwrite64)
+weak_alias (__libc_pwrite64, pwrite64)
+
+# define __libc_pwrite64(fd, buf, count, offset) \
+     static internal_function __emulate_pwrite64 (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite64.c>
+#endif
============================================================
Index: sysdeps/unix/sysv/linux/mips/pread.c
--- sysdeps/unix/sysv/linux/mips/pread.c	created
+++ sysdeps/unix/sysv/linux/mips/pread.c	Tue May 30 19:59:16 2000	1.1
@@ -0,0 +1,71 @@
+/* Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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 <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
+static ssize_t __emulate_pread (int fd, void *buf, size_t count,
+				off_t offset) internal_function;
+# endif
+extern ssize_t __syscall_pread (int fd, void *buf, size_t count, int dummy,
+				off_t offset_hi, off_t offset_lo);
+
+
+
+ssize_t
+__libc_pread (fd, buf, count, offset)
+     int fd;
+     void *buf;
+     size_t count;
+     off_t offset;
+{
+  ssize_t result;
+
+  /* First try the syscall.  */
+# if defined(__MIPSEB__)
+  result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0, 0, offset);
+# elif defined(__MIPSEL__)
+  result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0, offset, 0);
+# endif
+# if __ASSUME_PREAD_SYSCALL == 0
+  if (result == -1 && errno == ENOSYS)
+    /* No system call available.  Use the emulation.  */
+    result = __emulate_pread (fd, buf, count, offset);
+# endif
+  return result;
+}
+
+strong_alias (__libc_pread, __pread)
+weak_alias (__libc_pread, pread)
+
+# define __libc_pread(fd, buf, count, offset) \
+     static internal_function __emulate_pread (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread.c>
+#endif
============================================================
Index: sysdeps/unix/sysv/linux/mips/pwrite.c
--- sysdeps/unix/sysv/linux/mips/pwrite.c	created
+++ sysdeps/unix/sysv/linux/mips/pwrite.c	Tue May 30 19:59:16 2000	1.1
@@ -0,0 +1,71 @@
+/* Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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 <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+extern ssize_t __syscall_pwrite (int fd, const void *buf, size_t count,
+				 int dummy, off_t offset_hi, off_t offset_lo);
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
+				 off_t offset) internal_function;
+# endif
+
+ssize_t
+__libc_pwrite (fd, buf, count, offset)
+     int fd;
+     const void *buf;
+     size_t count;
+     off_t offset;
+{
+  ssize_t result;
+
+  /* First try the syscall.  */
+# if defined(__MIPSEB__)
+  result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, 0, offset);
+# elif defined(__MIPSEL__)
+  result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, offset, 0);
+# endif
+# if __ASSUME_PWRITE_SYSCALL == 0
+  if (result == -1 && errno == ENOSYS)
+    /* No system call available.  Use the emulation.  */
+    result = __emulate_pwrite (fd, buf, count, offset);
+# endif
+
+  return result;
+}
+
+strong_alias (__libc_pwrite, __pwrite)
+weak_alias (__libc_pwrite, pwrite)
+
+# define __libc_pwrite(fd, buf, count, offset) \
+     static internal_function __emulate_pwrite (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite.c>
+#endif

-- 
 Andreas Jaeger
  SuSE Labs aj@suse.de
   private aj@arthur.inka.de

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]