]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/readv.c
Update.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / readv.c
CommitLineData
e61abf83
UD
1/* readv supports all Linux kernels >= 2.0.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 read to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
19
20#include <errno.h>
21#include <stddef.h>
22#include <sys/param.h>
23#include <sys/uio.h>
24
25extern ssize_t __syscall_readv __P ((int, __const struct iovec *, int));
26
27
28/* Not all versions of the kernel support the large number of records. */
c57abfa7
UD
29#ifndef UIO_FASTIOV
30# define UIO_FASTIOV 8 /* 8 is a safe number. */
e61abf83
UD
31#endif
32
33
c57abfa7 34/* We should deal with kernel which have a smaller UIO_FASTIOV as well
e61abf83
UD
35 as a very big count. */
36ssize_t
37readv (fd, vector, count)
38 int fd;
39 const struct iovec *vector;
40 int count;
41{
42 int errno_saved = errno;
43 ssize_t bytes_read;
44
45 bytes_read = __syscall_readv (fd, vector, count);
46
c57abfa7 47 if (bytes_read < 0 && errno == EINVAL && count > UIO_FASTIOV)
e61abf83
UD
48 {
49 int i;
50
51 /* Restore the old error value as if nothing happened. */
52 __set_errno (errno_saved);
53
54 bytes_read = 0;
c57abfa7 55 for (i = 0; i < count; i += UIO_FASTIOV)
e61abf83
UD
56 {
57 ssize_t bytes = __syscall_readv (fd, vector + i,
c57abfa7 58 MIN (count - i, UIO_FASTIOV));
e61abf83
UD
59
60 if (bytes < 0)
61 return bytes;
62
63 bytes_read += bytes;
64 }
65 }
66
67 return bytes_read;
68}