diff options
Diffstat (limited to 'libc/sysdeps/linux/common/writev.c')
-rw-r--r-- | libc/sysdeps/linux/common/writev.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/common/writev.c b/libc/sysdeps/linux/common/writev.c index 4979fade9..cfb758974 100644 --- a/libc/sysdeps/linux/common/writev.c +++ b/libc/sysdeps/linux/common/writev.c @@ -2,6 +2,7 @@ /* * writev() for uClibc * + * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com> * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> * * GNU Library General Public License (LGPL) version 2 or later. @@ -9,5 +10,42 @@ #include "syscalls.h" #include <sys/uio.h> + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <errno.h> +#include <sysdep-cancel.h> + +/* We should deal with kernel which have a smaller UIO_FASTIOV as well + as a very big count. */ +static ssize_t __writev (int fd, const struct iovec *vector, int count) +{ + ssize_t bytes_written; + + bytes_written = INLINE_SYSCALL (writev, 3, fd, vector, count); + + if (bytes_written >= 0 || errno != EINVAL || count <= UIO_FASTIOV) + return bytes_written; + + /* glibc tries again, but we do not. */ + //return __atomic_writev_replacement (fd, vector, count); + + return -1; +} + +ssize_t writev (int fd, const struct iovec *vector, int count) +{ + if (SINGLE_THREAD_P) + return __writev (fd, vector, count); + + int oldtype = LIBC_CANCEL_ASYNC (); + + ssize_t result = __writev (fd, vector, count); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +#else _syscall3(ssize_t, writev, int, filedes, const struct iovec *, vector, int, count); +#endif |