sendfile.c 1.3 KB

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