getrlimit.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * getrlimit() for uClibc
  3. *
  4. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  5. *
  6. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  7. */
  8. #include <sys/syscall.h>
  9. #include <sys/resource.h>
  10. #include <bits/wordsize.h>
  11. #include <stddef.h> // needed for NULL to be defined
  12. /* Only wrap getrlimit if the new ugetrlimit is not present and getrlimit sucks */
  13. #if defined(__NR_ugetrlimit)
  14. /* just call ugetrlimit() */
  15. # define __NR___syscall_ugetrlimit __NR_ugetrlimit
  16. static __always_inline
  17. _syscall2(int, __syscall_ugetrlimit, enum __rlimit_resource, resource,
  18. struct rlimit *, rlim)
  19. int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits)
  20. {
  21. return __syscall_ugetrlimit(resource, rlimits);
  22. }
  23. libc_hidden_def(getrlimit)
  24. #elif defined(__NR_prlimit64)
  25. /* Use prlimit64 if present, the prlimit64 syscall is free from a back
  26. compatibility stuff for an old getrlimit */
  27. # if __WORDSIZE == 32 && !defined(__USE_FILE_OFFSET64)
  28. /* If struct rlimit has 64-bit fields (if __WORDSIZE == 64 or __USE_FILE_OFFSET64
  29. is defined), then use getrlimit as an alias to getrlimit64, see getrlimit64.c */
  30. int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits)
  31. {
  32. struct rlimit64 rlimits64;
  33. int res = INLINE_SYSCALL (prlimit64, 4, 0, resource, NULL, &rlimits64);
  34. if (res == 0) {
  35. /* If the syscall succeeds but the values do not fit into a
  36. rlimit structure set EOVERFLOW errno and retrun -1. */
  37. rlimits->rlim_cur = rlimits64.rlim_cur;
  38. if (rlimits64.rlim_cur != rlimits->rlim_cur) {
  39. if (rlimits64.rlim_cur != RLIM64_INFINITY) {
  40. __set_errno(EOVERFLOW);
  41. return -1;
  42. }
  43. rlimits->rlim_cur = RLIM_INFINITY;
  44. }
  45. rlimits->rlim_max = rlimits64.rlim_max;
  46. if (rlimits64.rlim_max != rlimits->rlim_max) {
  47. if (rlimits64.rlim_max != RLIM64_INFINITY) {
  48. __set_errno(EOVERFLOW);
  49. return -1;
  50. }
  51. rlimits->rlim_max = RLIM_INFINITY;
  52. }
  53. }
  54. return res;
  55. }
  56. libc_hidden_def(getrlimit)
  57. # endif
  58. #else
  59. # if !defined(__UCLIBC_HANDLE_OLDER_RLIMIT__)
  60. /* We don't need to wrap getrlimit() */
  61. _syscall2(int, getrlimit, __rlimit_resource_t, resource,
  62. struct rlimit *, rlim)
  63. # else
  64. /* we have to handle old style getrlimit() */
  65. # define __NR___syscall_getrlimit __NR_getrlimit
  66. static __always_inline
  67. _syscall2(int, __syscall_getrlimit, int, resource, struct rlimit *, rlim)
  68. int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits)
  69. {
  70. int result;
  71. result = __syscall_getrlimit(resource, rlimits);
  72. if (result == -1)
  73. return result;
  74. /* We might have to correct the limits values. Since the old values
  75. * were signed the infinity value is too small. */
  76. if (rlimits->rlim_cur == RLIM_INFINITY >> 1)
  77. rlimits->rlim_cur = RLIM_INFINITY;
  78. if (rlimits->rlim_max == RLIM_INFINITY >> 1)
  79. rlimits->rlim_max = RLIM_INFINITY;
  80. return result;
  81. }
  82. # endif
  83. libc_hidden_def(getrlimit)
  84. #endif