writev.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * writev() for uClibc
  4. *
  5. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  6. *
  7. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  8. */
  9. #include <sys/syscall.h>
  10. #include <sys/uio.h>
  11. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  12. #include <errno.h>
  13. #include <sysdep-cancel.h>
  14. /* We should deal with kernel which have a smaller UIO_FASTIOV as well
  15. as a very big count. */
  16. static ssize_t __writev (int fd, const struct iovec *vector, int count)
  17. {
  18. ssize_t bytes_written;
  19. bytes_written = INLINE_SYSCALL (writev, 3, fd, vector, count);
  20. if (bytes_written >= 0 || errno != EINVAL || count <= UIO_FASTIOV)
  21. return bytes_written;
  22. /* glibc tries again, but we do not. */
  23. /* return __atomic_writev_replacement (fd, vector, count); */
  24. return -1;
  25. }
  26. ssize_t writev (int fd, const struct iovec *vector, int count)
  27. {
  28. if (SINGLE_THREAD_P)
  29. return __writev (fd, vector, count);
  30. int oldtype = LIBC_CANCEL_ASYNC ();
  31. ssize_t result = __writev (fd, vector, count);
  32. LIBC_CANCEL_RESET (oldtype);
  33. return result;
  34. }
  35. #else
  36. _syscall3(ssize_t, writev, int, filedes, const struct iovec *, vector,
  37. int, count)
  38. #endif