aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--gshadow/sgetsgent_r.c7
-rw-r--r--misc/preadv.c2
-rw-r--r--misc/preadv64.c2
-rw-r--r--misc/pwritev.c2
-rw-r--r--misc/pwritev64.c2
-rw-r--r--misc/sys/uio.h8
-rw-r--r--sysdeps/posix/preadv.c2
-rw-r--r--sysdeps/posix/pwritev.c34
-rw-r--r--sysdeps/unix/sysv/linux/preadv.c10
-rw-r--r--sysdeps/unix/sysv/linux/pwritev.c10
11 files changed, 55 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index f510a30f1b..c3c48043e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
2009-04-23 Ulrich Drepper <drepper@redhat.com>
+ * sysdeps/unix/sysv/linux/preadv.c: The kernel API changed. Adjust.
+ * sysdeps/unix/sysv/linux/pwritev.c: Likewise.
+
+2009-04-23 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/posix/pwritev.c (PWRITEV): Fix up comment. Copy
+ data from vector to temporary buffer and call PWRITEV after it
+ instead of vice versa.
+ * sysdeps/posix/preadv.c: Fix up comment.
+ * misc/preadv.c: Likewise.
+ * misc/preadv64.c: Likewise.
+ * misc/pwritev.c: Likewise.
+ * misc/pwritev64.c: Likewise.
+ * misc/sys/uio.h (preadv, pwritev, preadv64, pwritev64): Likewise.
+
+2009-04-23 Ulrich Drepper <drepper@redhat.com>
+
* shadow/sgetspent_r.c (__sgetspent_r): Recognize too small buffers.
* shadow/Makefile (tests): Add tst-shadow.
diff --git a/gshadow/sgetsgent_r.c b/gshadow/sgetsgent_r.c
index 72c51fe26b..2292719af9 100644
--- a/gshadow/sgetsgent_r.c
+++ b/gshadow/sgetsgent_r.c
@@ -58,7 +58,12 @@ __sgetsgent_r (const char *string, struct sgrp *resbuf, char *buffer,
{
char *sp;
if (string < buffer || string >= buffer + buflen)
- sp = strncpy (buffer, string, buflen);
+ {
+ buffer[buflen - 1] = '\0';
+ sp = strncpy (buffer, string, buflen);
+ if (buffer[buflen - 1] != '\0')
+ return ERANGE;
+ }
else
sp = (char *) string;
diff --git a/misc/preadv.c b/misc/preadv.c
index 3e2cc689e6..facd8ca017 100644
--- a/misc/preadv.c
+++ b/misc/preadv.c
@@ -24,7 +24,7 @@
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
+ 'pread' (see <unistd.h>) except that data are put in VECTOR instead
of a contiguous buffer. */
ssize_t
preadv (fd, vector, count, offset)
diff --git a/misc/preadv64.c b/misc/preadv64.c
index ea675bb359..4b4e5717f8 100644
--- a/misc/preadv64.c
+++ b/misc/preadv64.c
@@ -24,7 +24,7 @@
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
+ 'pread' (see <unistd.h>) except that data are put in VECTOR instead
of a contiguous buffer. */
ssize_t
preadv64 (fd, vector, count, offset)
diff --git a/misc/pwritev.c b/misc/pwritev.c
index d45ed23351..2ee47708e1 100644
--- a/misc/pwritev.c
+++ b/misc/pwritev.c
@@ -23,7 +23,7 @@
/* 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
+ written in the order specified. Operates just like 'pwrite' (see
<unistd.h>) except that the data are taken from VECTOR instead of a
contiguous buffer. */
ssize_t
diff --git a/misc/pwritev64.c b/misc/pwritev64.c
index fe95857554..6cff749083 100644
--- a/misc/pwritev64.c
+++ b/misc/pwritev64.c
@@ -23,7 +23,7 @@
/* 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
+ written in the order specified. Operates just like 'pwrite' (see
<unistd.h>) except that the data are taken from VECTOR instead of a
contiguous buffer. */
ssize_t
diff --git a/misc/sys/uio.h b/misc/sys/uio.h
index a3c782917a..05d956bfd3 100644
--- a/misc/sys/uio.h
+++ b/misc/sys/uio.h
@@ -58,7 +58,7 @@ extern ssize_t writev (int __fd, __const struct iovec *__iovec, int __count)
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
+ 'pread' (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
@@ -69,7 +69,7 @@ extern ssize_t preadv (int __fd, __const struct iovec *__iovec, int __count,
/* 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
+ written in the order specified. Operates just like 'pwrite' (see
<unistd.h>) except that the data are taken from IOVEC instead of a
contiguous buffer.
@@ -96,7 +96,7 @@ extern ssize_t __REDIRECT (pwritev, (int __fd, __const struct iovec *__iovec,
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
+ 'pread' (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
@@ -107,7 +107,7 @@ extern ssize_t preadv64 (int __fd, __const struct iovec *__iovec, int __count,
/* 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
+ written in the order specified. Operates just like 'pwrite' (see
<unistd.h>) except that the data are taken from IOVEC instead of a
contiguous buffer.
diff --git a/sysdeps/posix/preadv.c b/sysdeps/posix/preadv.c
index 3d975226cf..791077399e 100644
--- a/sysdeps/posix/preadv.c
+++ b/sysdeps/posix/preadv.c
@@ -48,7 +48,7 @@ ifree (char **ptrp)
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
+ 'pread' (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)
diff --git a/sysdeps/posix/pwritev.c b/sysdeps/posix/pwritev.c
index 0b6627dc9d..f2f0574aac 100644
--- a/sysdeps/posix/pwritev.c
+++ b/sysdeps/posix/pwritev.c
@@ -44,12 +44,12 @@ ifree (char **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. */
+/* 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. */
ssize_t
PWRITEV (int fd, const struct iovec *vector, int count, OFF_T offset)
{
@@ -81,26 +81,14 @@ PWRITEV (int fd, const struct iovec *vector, int count, OFF_T offset)
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;
+ char *ptr = buffer;
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;
- }
+ ptr = __mempcpy ((void *) ptr, (void *) vector[i].iov_base,
+ vector[i].iov_len);
- return bytes_read;
+ /* Write the data. */
+ return PWRITE (fd, buffer, bytes, offset);
}
#if __WORDSIZE == 64 && defined pwritev64
# undef pwritev64
diff --git a/sysdeps/unix/sysv/linux/preadv.c b/sysdeps/unix/sysv/linux/preadv.c
index 0d4a6c3803..72722ebc0d 100644
--- a/sysdeps/unix/sysv/linux/preadv.c
+++ b/sysdeps/unix/sysv/linux/preadv.c
@@ -37,6 +37,10 @@
# define OFF_T off_t
#endif
+#define LO_HI_LONG(val) \
+ (off_t) val, \
+ (off_t) ((((uint64_t) (val)) >> (sizeof (long) * 4)) >> (sizeof (long) * 4))
+
#ifndef __ASSUME_PREADV
static ssize_t PREADV_REPLACEMENT (int, __const struct iovec *,
int, OFF_T) internal_function;
@@ -55,15 +59,13 @@ PREADV (fd, vector, count, offset)
if (SINGLE_THREAD_P)
result = INLINE_SYSCALL (preadv, 5, fd, vector, count,
- (off_t) ((off64_t) offset >> 32),
- (off_t) (offset & 0xffffffff));
+ LO_HI_LONG (offset));
else
{
int oldtype = LIBC_CANCEL_ASYNC ();
result = INLINE_SYSCALL (preadv, 5, fd, vector, count,
- (off_t) ((off64_t) offset >> 32),
- (off_t) (offset & 0xffffffff));
+ LO_HI_LONG (offset));
LIBC_CANCEL_RESET (oldtype);
}
diff --git a/sysdeps/unix/sysv/linux/pwritev.c b/sysdeps/unix/sysv/linux/pwritev.c
index 5c30eae51f..2e9cbb2536 100644
--- a/sysdeps/unix/sysv/linux/pwritev.c
+++ b/sysdeps/unix/sysv/linux/pwritev.c
@@ -37,6 +37,10 @@
# define OFF_T off_t
#endif
+#define LO_HI_LONG(val) \
+ (off_t) val, \
+ (off_t) ((((uint64_t) (val)) >> (sizeof (long) * 4)) >> (sizeof (long) * 4))
+
#ifndef __ASSUME_PWRITEV
static ssize_t PWRITEV_REPLACEMENT (int, __const struct iovec *,
int, OFF_T) internal_function;
@@ -55,15 +59,13 @@ PWRITEV (fd, vector, count, offset)
if (SINGLE_THREAD_P)
result = INLINE_SYSCALL (pwritev, 5, fd, vector, count,
- (off_t) ((off64_t) offset >> 32),
- (off_t) (offset & 0xffffffff));
+ LO_HI_LONG (offset));
else
{
int oldtype = LIBC_CANCEL_ASYNC ();
result = INLINE_SYSCALL (pwritev, 5, fd, vector, count,
- (off_t) ((off64_t) offset >> 32),
- (off_t) (offset & 0xffffffff));
+ LO_HI_LONG (offset));
LIBC_CANCEL_RESET (oldtype);
}