diff options
author | Ulrich Drepper <drepper@redhat.com> | 2009-04-03 19:57:16 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2009-04-03 19:57:16 +0000 |
commit | e109c6124fe121618e42ba882e2a0af6e97b8efc (patch) | |
tree | 1e5ab3fe5ac14fe05fef1e21a6ef0653f1cce2b4 | |
parent | 7166c77ad06b44571398d641e00153145da04a2b (diff) | |
download | glibc-e109c6124fe121618e42ba882e2a0af6e97b8efc.zip glibc-e109c6124fe121618e42ba882e2a0af6e97b8efc.tar.gz glibc-e109c6124fe121618e42ba882e2a0af6e97b8efc.tar.bz2 |
* misc/Makefile (routines): Add preadv, preadv64, pwritev, pwritev64.
* misc/Versions: Export preadv, preadv64, pwritev, pwritev64 for
GLIBC_2.10.
* misc/sys/uio.h: Declare preadv, preadv64, pwritev, pwritev64.
* sysdeps/unix/sysv/linux/kernel-features.h: Add entries for preadv
and pwritev.
* misc/preadv.c: New file.
* misc/preadv64.c: New file.
* misc/pwritev.c: New file.
* misc/pwritev64.c: New file.
* sysdeps/posx/preadv.c: New file.
* sysdeps/posx/preadv64.c: New file.
* sysdeps/posx/pwritev.c: New file.
* sysdeps/posx/pwritev64.c: New file.
* sysdeps/unix/sysv/linux/preadv.c: New file.
* sysdeps/unix/sysv/linux/preadv64.c: New file.
* sysdeps/unix/sysv/linux/pwritev.c: New file.
* sysdeps/unix/sysv/linux/pwritev64.c: New file.
* sysdeps/unix/sysv/linux/wordsize-64/preadv64.c: New file.
* sysdeps/unix/sysv/linux/wordsize-64/pwritev64.c: New file.
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | NEWS | 13 | ||||
-rw-r--r-- | misc/Makefile | 2 | ||||
-rw-r--r-- | misc/Versions | 3 | ||||
-rw-r--r-- | misc/preadv.c | 41 | ||||
-rw-r--r-- | misc/preadv64.c | 41 | ||||
-rw-r--r-- | misc/pwritev.c | 41 | ||||
-rw-r--r-- | misc/pwritev64.c | 41 | ||||
-rw-r--r-- | misc/sys/uio.h | 83 | ||||
-rw-r--r-- | sysdeps/posix/preadv.c | 108 | ||||
-rw-r--r-- | sysdeps/posix/preadv64.c | 9 | ||||
-rw-r--r-- | sysdeps/posix/pwritev.c | 108 | ||||
-rw-r--r-- | sysdeps/posix/pwritev64.c | 9 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/kernel-features.h | 7 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/preadv.c | 88 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/preadv64.c | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/pwritev.c | 88 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/pwritev64.c | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/wordsize-64/preadv64.c | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/wordsize-64/pwritev64.c | 1 |
20 files changed, 708 insertions, 9 deletions
@@ -1,5 +1,26 @@ 2009-04-03 Ulrich Drepper <drepper@redhat.com> + * misc/Makefile (routines): Add preadv, preadv64, pwritev, pwritev64. + * misc/Versions: Export preadv, preadv64, pwritev, pwritev64 for + GLIBC_2.10. + * misc/sys/uio.h: Declare preadv, preadv64, pwritev, pwritev64. + * sysdeps/unix/sysv/linux/kernel-features.h: Add entries for preadv + and pwritev. + * misc/preadv.c: New file. + * misc/preadv64.c: New file. + * misc/pwritev.c: New file. + * misc/pwritev64.c: New file. + * sysdeps/posx/preadv.c: New file. + * sysdeps/posx/preadv64.c: New file. + * sysdeps/posx/pwritev.c: New file. + * sysdeps/posx/pwritev64.c: New file. + * sysdeps/unix/sysv/linux/preadv.c: New file. + * sysdeps/unix/sysv/linux/preadv64.c: New file. + * sysdeps/unix/sysv/linux/pwritev.c: New file. + * sysdeps/unix/sysv/linux/pwritev64.c: New file. + * sysdeps/unix/sysv/linux/wordsize-64/preadv64.c: New file. + * sysdeps/unix/sysv/linux/wordsize-64/pwritev64.c: New file. + * sysdeps/unix/sysv/linux/readv.c (__libc_readv): Fix calling of compatibility code. * sysdeps/unix/sysv/linux/writev.c (__libc_writev): Likewise. @@ -1,4 +1,4 @@ -GNU C Library NEWS -- history of user-visible changes. 2009-3-14 +GNU C Library NEWS -- history of user-visible changes. 2009-4-3 Copyright (C) 1992-2008, 2009 Free Software Foundation, Inc. See the end for copying conditions. @@ -7,7 +7,11 @@ using `glibc' in the "product" field. Version 2.10 +* New interfaces: preadv, preadv64, pwritev, pwritev64 + Implemented by Ulrich Drepper. + * New Linux interfaces: accept4, fallocate, fallocate64. + Implemented by Ulrich Drepper. * Correct declarations of string function when used in C++ code. This could lead to compile error for invalid C++ code. @@ -24,6 +28,13 @@ Version 2.10 * Support for selecting between multiple function definitions at runtime using STT_GNU_IFUNC symbols. Implemented by Ulrich Drepper. +* The libcrypt library can now use the hash function implementations in + NSS. Implemented by Ulrich Drepper. + +* The malloc implementation can be compiled to be less memory efficient + but higher performing in multi-threaded programs. + Implemented by Ulrich Drepper. + * New locale: nan_TW@latin diff --git a/misc/Makefile b/misc/Makefile index a256068..1357634 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -34,7 +34,7 @@ headers := sys/uio.h bits/uio.h sys/ioctl.h bits/ioctls.h bits/ioctl-types.h \ bits/syslog.h bits/syslog-ldbl.h bits/syslog-path.h bits/error.h routines := brk sbrk sstk ioctl \ - readv writev \ + readv writev preadv preadv64 pwritev pwritev64 \ setreuid setregid \ seteuid setegid \ getpagesize \ diff --git a/misc/Versions b/misc/Versions index b182f12..c930eea 100644 --- a/misc/Versions +++ b/misc/Versions @@ -137,4 +137,7 @@ libc { GLIBC_2.7 { mkostemp; mkostemp64; } + GLIBC_2.10 { + preadv; preadv64; pwritev; pwritev64; + } } diff --git a/misc/preadv.c b/misc/preadv.c new file mode 100644 index 0000000..3e2cc68 --- /dev/null +++ b/misc/preadv.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 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. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/uio.h> + +/* Read data from file descriptor FD at the given position OFFSET + without change the file pointer, and put the result in the buffers + described by VECTOR, which is a vector of COUNT 'struct iovec's. + The buffers are filled in the order specified. Operates just like + 'read' (see <unistd.h>) except that data are put in VECTOR instead + of a contiguous buffer. */ +ssize_t +preadv (fd, vector, count, offset) + int fd; + const struct iovec *vector; + int count; + off_t offset; +{ + __set_errno (ENOSYS); + return -1; +} + +stub_warning (preadv) +#include <stub-tag.h> diff --git a/misc/preadv64.c b/misc/preadv64.c new file mode 100644 index 0000000..ea675bb --- /dev/null +++ b/misc/preadv64.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 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. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/uio.h> + +/* Read data from file descriptor FD at the given position OFFSET + without change the file pointer, and put the result in the buffers + described by VECTOR, which is a vector of COUNT 'struct iovec's. + The buffers are filled in the order specified. Operates just like + 'read' (see <unistd.h>) except that data are put in VECTOR instead + of a contiguous buffer. */ +ssize_t +preadv64 (fd, vector, count, offset) + int fd; + const struct iovec *vector; + int count; + off64_t offset; +{ + __set_errno (ENOSYS); + return -1; +} + +stub_warning (preadv64) +#include <stub-tag.h> diff --git a/misc/pwritev.c b/misc/pwritev.c new file mode 100644 index 0000000..d45ed23 --- /dev/null +++ b/misc/pwritev.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 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. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/uio.h> + +/* Write data pointed by the buffers described by VECTOR, which is a + vector of COUNT 'struct iovec's, to file descriptor FD at the given + position OFFSET without change the file pointer. The data is + written in the order specified. Operates just like 'write' (see + <unistd.h>) except that the data are taken from VECTOR instead of a + contiguous buffer. */ +ssize_t +pwritev (fd, vector, count, offset) + int fd; + const struct iovec *vector; + int count; + off_t offset; +{ + __set_errno (ENOSYS); + return -1; +} + +stub_warning (pwritev) +#include <stub-tag.h> diff --git a/misc/pwritev64.c b/misc/pwritev64.c new file mode 100644 index 0000000..fe95857 --- /dev/null +++ b/misc/pwritev64.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 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. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/uio.h> + +/* Write data pointed by the buffers described by VECTOR, which is a + vector of COUNT 'struct iovec's, to file descriptor FD at the given + position OFFSET without change the file pointer. The data is + written in the order specified. Operates just like 'write' (see + <unistd.h>) except that the data are taken from VECTOR instead of a + contiguous buffer. */ +ssize_t +pwritev64 (fd, vector, count, offset) + int fd; + const struct iovec *vector; + int count; + off64_t offset; +{ + __set_errno (ENOSYS); + return -1; +} + +stub_warning (pwritev64) +#include <stub-tag.h> diff --git a/misc/sys/uio.h b/misc/sys/uio.h index 1b203f7..a3c7829 100644 --- a/misc/sys/uio.h +++ b/misc/sys/uio.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 96, 97, 98, 99, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1991,1992,1996-1999,2003,2009 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 @@ -30,24 +30,93 @@ __BEGIN_DECLS /* Read data from file descriptor FD, and put the result in the - buffers described by IOVEC, which is a vector of COUNT `struct iovec's. + buffers described by IOVEC, which is a vector of COUNT 'struct iovec's. The buffers are filled in the order specified. - Operates just like `read' (see <unistd.h>) except that data are + Operates just like 'read' (see <unistd.h>) except that data are put in IOVEC instead of a contiguous buffer. This function is a cancellation point and therefore not marked with __THROW. */ -extern ssize_t readv (int __fd, __const struct iovec *__iovec, int __count); +extern ssize_t readv (int __fd, __const struct iovec *__iovec, int __count) + __wur; /* Write data pointed by the buffers described by IOVEC, which - is a vector of COUNT `struct iovec's, to file descriptor FD. + is a vector of COUNT 'struct iovec's, to file descriptor FD. The data is written in the order specified. - Operates just like `write' (see <unistd.h>) except that the data + Operates just like 'write' (see <unistd.h>) except that the data are taken from IOVEC instead of a contiguous buffer. This function is a cancellation point and therefore not marked with __THROW. */ -extern ssize_t writev (int __fd, __const struct iovec *__iovec, int __count); +extern ssize_t writev (int __fd, __const struct iovec *__iovec, int __count) + __wur; + + +#ifdef __USE_BSD +# ifndef __USE_FILE_OFFSET64 +/* Read data from file descriptor FD at the given position OFFSET + without change the file pointer, and put the result in the buffers + described by IOVEC, which is a vector of COUNT 'struct iovec's. + The buffers are filled in the order specified. Operates just like + 'read' (see <unistd.h>) except that data are put in IOVEC instead + of a contiguous buffer. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern ssize_t preadv (int __fd, __const struct iovec *__iovec, int __count, + __off_t __offset) __wur; + +/* Write data pointed by the buffers described by IOVEC, which is a + vector of COUNT 'struct iovec's, to file descriptor FD at the given + position OFFSET without change the file pointer. The data is + written in the order specified. Operates just like 'write' (see + <unistd.h>) except that the data are taken from IOVEC instead of a + contiguous buffer. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern ssize_t pwritev (int __fd, __const struct iovec *__iovec, int __count, + __off_t __offset) __wur; +# else +# ifdef __REDIRECT +extern ssize_t __REDIRECT (preadv, (int __fd, __const struct iovec *__iovec, + int __count, __off_t __offset), + preadv64) __wur; +extern ssize_t __REDIRECT (pwritev, (int __fd, __const struct iovec *__iovec, + int __count, __off_t __offset), + pwritev64) __wur; +# else +# define preadv preadv64 +# define pwritev pwritev64 +# endif +# endif + +# ifdef __USE_LARGEFILE64 +/* Read data from file descriptor FD at the given position OFFSET + without change the file pointer, and put the result in the buffers + described by IOVEC, which is a vector of COUNT 'struct iovec's. + The buffers are filled in the order specified. Operates just like + 'read' (see <unistd.h>) except that data are put in IOVEC instead + of a contiguous buffer. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern ssize_t preadv64 (int __fd, __const struct iovec *__iovec, int __count, + __off64_t __offset) __wur; + +/* Write data pointed by the buffers described by IOVEC, which is a + vector of COUNT 'struct iovec's, to file descriptor FD at the given + position OFFSET without change the file pointer. The data is + written in the order specified. Operates just like 'write' (see + <unistd.h>) except that the data are taken from IOVEC instead of a + contiguous buffer. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern ssize_t pwritev64 (int __fd, __const struct iovec *__iovec, int __count, + __off64_t __offset) __wur; +# endif +#endif /* Use BSD */ __END_DECLS diff --git a/sysdeps/posix/preadv.c b/sysdeps/posix/preadv.c new file mode 100644 index 0000000..e697604 --- /dev/null +++ b/sysdeps/posix/preadv.c @@ -0,0 +1,108 @@ +/* Copyright (C) 2009 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. */ + +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <limits.h> +#include <stdbool.h> +#include <sys/param.h> +#if __WORDSIZE == 64 && !defined PREADV +/* Hide the preadv64 declaration. */ +# define preadv64 __redirect_preadv64 +#endif +#include <sys/uio.h> +#include <bits/wordsize.h> + +#ifndef PREADV +# define PREADV preadv +# define PREAD __pread +# define OFF_T off_t +#endif + + +static void +ifree (char **ptrp) +{ + free (*ptrp); +} + + +/* Read data from file descriptor FD at the given position OFFSET + without change the file pointer, and put the result in the buffers + described by VECTOR, which is a vector of COUNT 'struct iovec's. + The buffers are filled in the order specified. Operates just like + 'read' (see <unistd.h>) except that data are put in VECTOR instead + of a contiguous buffer. */ +ssize_t +PREADV (int fd, const struct iovec *vector, int count, OFF_T offset) +{ + /* Find the total number of bytes to be read. */ + size_t bytes = 0; + for (int i = 0; i < count; ++i) + { + /* Check for ssize_t overflow. */ + if (SSIZE_MAX - bytes < vector[i].iov_len) + { + __set_errno (EINVAL); + return -1; + } + bytes += vector[i].iov_len; + } + + /* Allocate a temporary buffer to hold the data. We should normally + use alloca since it's faster and does not require synchronization + with other threads. But we cannot if the amount of memory + required is too large. */ + char *buffer; + char *malloced_buffer __attribute__ ((__cleanup__ (ifree))) = NULL; + if (__libc_use_alloca (bytes)) + buffer = (char *) __alloca (bytes); + else + { + malloced_buffer = buffer = (char *) malloc (bytes); + if (buffer == NULL) + return -1; + } + + /* Read the data. */ + ssize_t bytes_read = PREAD (fd, buffer, bytes, offset); + if (bytes_read <= 0) + return -1; + + /* Copy the data from BUFFER into the memory specified by VECTOR. */ + bytes = bytes_read; + for (int i = 0; i < count; ++i) + { + size_t copy = MIN (vector[i].iov_len, bytes); + + (void) memcpy ((void *) vector[i].iov_base, (void *) buffer, copy); + + buffer += copy; + bytes -= copy; + if (bytes == 0) + break; + } + + return bytes_read; +} +#if __WORDSIZE == 64 && defined preadv64 +# undef preadv64 +strong_alias (preadv, preadv64) +#endif diff --git a/sysdeps/posix/preadv64.c b/sysdeps/posix/preadv64.c new file mode 100644 index 0000000..1986223 --- /dev/null +++ b/sysdeps/posix/preadv64.c @@ -0,0 +1,9 @@ +#include <bits/wordsize.h> + +#if __WORDSIZE == 32 +# define PREADV preadv64 +# define PREAD __pread64 +# define OFF_T off64_t + +# include "preadv.c" +#endif diff --git a/sysdeps/posix/pwritev.c b/sysdeps/posix/pwritev.c new file mode 100644 index 0000000..0b6627d --- /dev/null +++ b/sysdeps/posix/pwritev.c @@ -0,0 +1,108 @@ +/* Copyright (C) 2009 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. */ + +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <limits.h> +#include <stdbool.h> +#include <sys/param.h> +#if __WORDSIZE == 64 && !defined PWRITEV +/* Hide the pwritev64 declaration. */ +# define pwritev64 __redirect_pwritev64 +#endif +#include <sys/uio.h> +#include <bits/wordsize.h> + +#ifndef PWRITEV +# define PWRITEV pwritev +# define PWRITE __pwrite +# define OFF_T off_t +#endif + + +static void +ifree (char **ptrp) +{ + free (*ptrp); +} + + +/* Read data from file descriptor FD at the given position OFFSET + without change the file pointer, and put the result in the buffers + described by VECTOR, which is a vector of COUNT 'struct iovec's. + The buffers are filled in the order specified. Operates just like + 'read' (see <unistd.h>) except that data are put in VECTOR instead + of a contiguous buffer. */ +ssize_t +PWRITEV (int fd, const struct iovec *vector, int count, OFF_T offset) +{ + /* Find the total number of bytes to be read. */ + size_t bytes = 0; + for (int i = 0; i < count; ++i) + { + /* Check for ssize_t overflow. */ + if (SSIZE_MAX - bytes < vector[i].iov_len) + { + __set_errno (EINVAL); + return -1; + } + bytes += vector[i].iov_len; + } + + /* Allocate a temporary buffer to hold the data. We should normally + use alloca since it's faster and does not require synchronization + with other threads. But we cannot if the amount of memory + required is too large. */ + char *buffer; + char *malloced_buffer __attribute__ ((__cleanup__ (ifree))) = NULL; + if (__libc_use_alloca (bytes)) + buffer = (char *) __alloca (bytes); + else + { + malloced_buffer = buffer = (char *) malloc (bytes); + if (buffer == NULL) + return -1; + } + + /* Read the data. */ + ssize_t bytes_read = PWRITE (fd, buffer, bytes, offset); + if (bytes_read <= 0) + return -1; + + /* Copy the data from BUFFER into the memory specified by VECTOR. */ + bytes = bytes_read; + for (int i = 0; i < count; ++i) + { + size_t copy = MIN (vector[i].iov_len, bytes); + + (void) memcpy ((void *) vector[i].iov_base, (void *) buffer, copy); + + buffer += copy; + bytes -= copy; + if (bytes == 0) + break; + } + + return bytes_read; +} +#if __WORDSIZE == 64 && defined pwritev64 +# undef pwritev64 +strong_alias (pwritev, pwritev64) +#endif diff --git a/sysdeps/posix/pwritev64.c b/sysdeps/posix/pwritev64.c new file mode 100644 index 0000000..4948d2e --- /dev/null +++ b/sysdeps/posix/pwritev64.c @@ -0,0 +1,9 @@ +#include <bits/wordsize.h> + +#if __WORDSIZE == 32 +# define PWRITEV pwritev64 +# define PWRITE __pwrite64 +# define OFF_T off64_t + +# include "pwritev.c" +#endif diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 9053df1..a640765 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -529,3 +529,10 @@ #if __LINUX_KERNEL_VERSION >= 0x02061d # define __ASSUME_FUTEX_CLOCK_REALTIME 1 #endif + +/* Support for preadv and pwritev was added in 2.6.30. */ +#if __LINUX_KERNEL_VERSION >= 0x02061e \ + && (defined __i386__ || defined __x86_64__) +# define __ASSUME_PREADV 1 +# define __ASSUME_PWRITEV 1 +#endif diff --git a/sysdeps/unix/sysv/linux/preadv.c b/sysdeps/unix/sysv/linux/preadv.c new file mode 100644 index 0000000..e2f8238 --- /dev/null +++ b/sysdeps/unix/sysv/linux/preadv.c @@ -0,0 +1,88 @@ +/* Copyright (C) 2009 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. */ + +#include <errno.h> +#include <stddef.h> +#include <sys/param.h> +#if __WORDSIZE == 64 +/* Hide the preadv64 declaration. */ +# define preadv64 __redirect_preadv64 +#endif +#include <sys/uio.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <kernel-features.h> + +#ifndef PREADV +# define PREADV preadv +# define PREADV_REPLACEMENT __atomic_preadv_replacement +# define PREAD __pread +# define OFF_T off_t +#endif + +static ssize_t PREADV_REPLACEMENT (int, __const struct iovec *, + int, OFF_T) internal_function; + + +ssize_t +PREADV (fd, vector, count, offset) + int fd; + const struct iovec *vector; + int count; + OFF_T offset; +{ +#ifdef __NR_preadv + ssize_t result; + + if (SINGLE_THREAD_P) + result = INLINE_SYSCALL (preadv, 5, fd, vector, count, offset >> 32, + offset & 0xffffffff); + else + { + int oldtype = LIBC_CANCEL_ASYNC (); + + result = INLINE_SYSCALL (preadv, 5, fd, vector, count, offset >> 32, + offset & 0xffffffff); + + LIBC_CANCEL_RESET (oldtype); + } +# ifdef __ASSUME_PREADV + return result; +# endif +#endif + +#ifndef __ASSUME_PREADV +# ifdef __NR_preadv + if (result >= 0 || errno != ENOSYS) + return result; +# endif + + return PREADV_REPLACEMENT (fd, vector, count, offset); +#endif +} +#if __WORDSIZE == 64 +# undef preadv64 +strong_alias (preadv, preadv64) +#endif + +#ifndef __ASSUME_PREADV +# undef PREADV +# define PREADV static internal_function PREADV_REPLACEMENT +# include <sysdeps/posix/preadv.c> +#endif diff --git a/sysdeps/unix/sysv/linux/preadv64.c b/sysdeps/unix/sysv/linux/preadv64.c new file mode 100644 index 0000000..739df00 --- /dev/null +++ b/sysdeps/unix/sysv/linux/preadv64.c @@ -0,0 +1,6 @@ +#define PREADV preadv64 +#define PREADV_REPLACEMENT __atomic_preadv64_replacement +#define PREAD __pread64 +#define OFF_T off64_t + +#include "preadv.c" diff --git a/sysdeps/unix/sysv/linux/pwritev.c b/sysdeps/unix/sysv/linux/pwritev.c new file mode 100644 index 0000000..df430ff --- /dev/null +++ b/sysdeps/unix/sysv/linux/pwritev.c @@ -0,0 +1,88 @@ +/* Copyright (C) 2009 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. */ + +#include <errno.h> +#include <stddef.h> +#include <sys/param.h> +#if __WORDSIZE == 64 && !defined PWRITEV +/* Hide the pwritev64 declaration. */ +# define pwritev64 __redirect_pwritev64 +#endif +#include <sys/uio.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <kernel-features.h> + +#ifndef PWRITEV +# define PWRITEV pwritev +# define PWRITEV_REPLACEMENT __atomic_pwritev_replacement +# define PWRITE __pwrite +# define OFF_T off_t +#endif + +static ssize_t PWRITEV_REPLACEMENT (int, __const struct iovec *, + int, OFF_T) internal_function; + + +ssize_t +PWRITEV (fd, vector, count, offset) + int fd; + const struct iovec *vector; + int count; + OFF_T offset; +{ +#ifdef __NR_pwritev + ssize_t result; + + if (SINGLE_THREAD_P) + result = INLINE_SYSCALL (pwritev, 5, fd, vector, count, offset >> 32, + offset & 0xffffffff); + else + { + int oldtype = LIBC_CANCEL_ASYNC (); + + result = INLINE_SYSCALL (pwritev, 5, fd, vector, count, offset >> 32, + offset & 0xffffffff); + + LIBC_CANCEL_RESET (oldtype); + } +# ifdef __ASSUME_PWRITEV + return result; +# endif +#endif + +#ifndef __ASSUME_PWRITEV +# ifdef __NR_pwritev + if (result >= 0 || errno != ENOSYS) + return result; +# endif + + return PWRITEV_REPLACEMENT (fd, vector, count, offset); +#endif +} +#if __WORDSIZE == 64 && defined pwritev64 +# undef pwritev64 +strong_alias (pwritev, pwritev64) +#endif + +#ifndef __ASSUME_PWRITEV +# undef PWRITEV +# define PWRITEV static internal_function PWRITEV_REPLACEMENT +# include <sysdeps/posix/pwritev.c> +#endif diff --git a/sysdeps/unix/sysv/linux/pwritev64.c b/sysdeps/unix/sysv/linux/pwritev64.c new file mode 100644 index 0000000..1e8168f --- /dev/null +++ b/sysdeps/unix/sysv/linux/pwritev64.c @@ -0,0 +1,6 @@ +#define PWRITEV pwritev64 +#define PWRITEV_REPLACEMENT __atomic_pwritev64_replacement +#define PWRITE __pwrite64 +#define OFF_T off64_t + +#include "pwritev.c" diff --git a/sysdeps/unix/sysv/linux/wordsize-64/preadv64.c b/sysdeps/unix/sysv/linux/wordsize-64/preadv64.c new file mode 100644 index 0000000..fd9320c --- /dev/null +++ b/sysdeps/unix/sysv/linux/wordsize-64/preadv64.c @@ -0,0 +1 @@ +/* Empty since the preadv syscall is equivalent. */ diff --git a/sysdeps/unix/sysv/linux/wordsize-64/pwritev64.c b/sysdeps/unix/sysv/linux/wordsize-64/pwritev64.c new file mode 100644 index 0000000..8b72a29 --- /dev/null +++ b/sysdeps/unix/sysv/linux/wordsize-64/pwritev64.c @@ -0,0 +1 @@ +/* Empty since the pwritev syscall is equivalent. */ |