sendfile.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * sendfile() 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/sendfile.h>
  11. # include <bits/wordsize.h>
  12. #if defined __NR_sendfile
  13. _syscall4(ssize_t, sendfile, int, out_fd, int, in_fd, __off_t *, offset,
  14. size_t, count)
  15. # if defined __UCLIBC_HAS_LFS__ && (!defined __NR_sendfile64 || __WORDSIZE == 64)
  16. libc_hidden_def(sendfile64)
  17. strong_alias_untyped(sendfile,sendfile64)
  18. # endif
  19. #elif defined __NR_sendfile64 && !defined __NR_sendfile
  20. # include <unistd.h>
  21. # include <stddef.h>
  22. ssize_t sendfile(int out_fd, int in_fd, __off_t *offset, size_t count)
  23. {
  24. __off64_t off64, *off;
  25. ssize_t res;
  26. /*
  27. * Check if valid fds and valid pointers were passed
  28. * This does not prevent the user from passing
  29. * an arbitrary pointer causing a segfault or
  30. * other security issues
  31. */
  32. if (in_fd < 0 || out_fd < 0) {
  33. __set_errno(EBADF);
  34. return -1;
  35. }
  36. if (offset == NULL || (int)offset < 0) {
  37. __set_errno(EFAULT);
  38. return -1;
  39. }
  40. if (offset) {
  41. off = &off64;
  42. off64 = *offset;
  43. } else {
  44. off = NULL;
  45. }
  46. res = INLINE_SYSCALL(sendfile64, 4, out_fd, in_fd, off, count);
  47. if (res >= 0)
  48. *offset = off64;
  49. return res;
  50. }
  51. #endif