mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-12 14:20:13 +00:00
7a16bdbb9f
The fallback code of Linux wrapper for preadv2/pwritev2 executes regardless of the errno code for preadv2, instead of the case where the syscall is not supported. This fixes it by calling the fallback code iff errno is ENOSYS. The patch also adds tests for both invalid file descriptor and invalid iov_len and vector count. The only discrepancy between preadv2 and fallback code regarding error reporting is when an invalid flags are used. The fallback code bails out earlier with ENOTSUP instead of EINVAL/EBADF when the syscall is used. Checked on x86_64-linux-gnu on a 4.4.0 and 4.15.0 kernel. [BZ #23579] * misc/tst-preadvwritev2-common.c (do_test_with_invalid_fd): New test. * misc/tst-preadvwritev2.c, misc/tst-preadvwritev64v2.c (do_test): Call do_test_with_invalid_fd. * sysdeps/unix/sysv/linux/preadv2.c (preadv2): Use fallback code iff errno is ENOSYS. * sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise. * sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise. * sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise.
59 lines
1.9 KiB
C
59 lines
1.9 KiB
C
/* Linux implementation of preadv2.
|
|
Copyright (C) 2017-2018 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, see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include <sys/uio.h>
|
|
#include <sysdep-cancel.h>
|
|
|
|
#ifndef __OFF_T_MATCHES_OFF64_T
|
|
|
|
# if !defined (__NR_preadv2) && defined (__NR_pread64v2)
|
|
# define __NR_preadv2 __NR_pread64v2
|
|
# endif
|
|
|
|
ssize_t
|
|
preadv2 (int fd, const struct iovec *vector, int count, off_t offset,
|
|
int flags)
|
|
{
|
|
# ifdef __NR_preadv2
|
|
ssize_t result = SYSCALL_CANCEL (preadv2, fd, vector, count,
|
|
LO_HI_LONG (offset), flags);
|
|
if (result >= 0 || errno != ENOSYS)
|
|
return result;
|
|
# endif
|
|
/* Trying to emulate the preadv2 syscall flags is troublesome:
|
|
|
|
* We can not temporary change the file state of the O_DSYNC and O_SYNC
|
|
flags to emulate RWF_{D}SYNC (attempts to change the state of using
|
|
fcntl are silently ignored).
|
|
|
|
* IOCB_HIPRI requires the file opened in O_DIRECT and uses an internal
|
|
semantic not provided by any other flag (O_NONBLOCK for instance). */
|
|
|
|
if (flags != 0)
|
|
{
|
|
__set_errno (ENOTSUP);
|
|
return -1;
|
|
}
|
|
if (offset == -1)
|
|
return __readv (fd, vector, count);
|
|
else
|
|
return preadv (fd, vector, count, offset);
|
|
}
|
|
|
|
#endif
|