fdio.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. /**
  6. * \file fdio.c
  7. *
  8. * \brief Low-level compatibility wrappers for fd-based IO.
  9. **/
  10. #include "orconfig.h"
  11. #ifdef HAVE_UNISTD_H
  12. #include <unistd.h>
  13. #endif
  14. #ifdef _WIN32
  15. #include <windows.h>
  16. #endif
  17. #include "lib/fdio/fdio.h"
  18. #include "lib/cc/torint.h"
  19. #include "lib/err/torerr.h"
  20. #include <stdlib.h>
  21. /** @{ */
  22. /** Some old versions of Unix didn't define constants for these values,
  23. * and instead expect you to say 0, 1, or 2. */
  24. #ifndef SEEK_SET
  25. #define SEEK_SET 0
  26. #endif
  27. #ifndef SEEK_CUR
  28. #define SEEK_CUR 1
  29. #endif
  30. #ifndef SEEK_END
  31. #define SEEK_END 2
  32. #endif
  33. /** @} */
  34. /** Return the position of <b>fd</b> with respect to the start of the file. */
  35. off_t
  36. tor_fd_getpos(int fd)
  37. {
  38. #ifdef _WIN32
  39. return (off_t) _lseek(fd, 0, SEEK_CUR);
  40. #else
  41. return (off_t) lseek(fd, 0, SEEK_CUR);
  42. #endif
  43. }
  44. /** Move <b>fd</b> to the end of the file. Return -1 on error, 0 on success.
  45. * If the file is a pipe, do nothing and succeed.
  46. **/
  47. int
  48. tor_fd_seekend(int fd)
  49. {
  50. #ifdef _WIN32
  51. return _lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
  52. #else
  53. off_t rc = lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
  54. #ifdef ESPIPE
  55. /* If we get an error and ESPIPE, then it's a pipe or a socket of a fifo:
  56. * no need to worry. */
  57. if (rc < 0 && errno == ESPIPE)
  58. rc = 0;
  59. #endif /* defined(ESPIPE) */
  60. return (rc < 0) ? -1 : 0;
  61. #endif /* defined(_WIN32) */
  62. }
  63. /** Move <b>fd</b> to position <b>pos</b> in the file. Return -1 on error, 0
  64. * on success. */
  65. int
  66. tor_fd_setpos(int fd, off_t pos)
  67. {
  68. #ifdef _WIN32
  69. return _lseek(fd, pos, SEEK_SET) < 0 ? -1 : 0;
  70. #else
  71. return lseek(fd, pos, SEEK_SET) < 0 ? -1 : 0;
  72. #endif
  73. }
  74. /** Replacement for ftruncate(fd, 0): move to the front of the file and remove
  75. * all the rest of the file. Return -1 on error, 0 on success. */
  76. int
  77. tor_ftruncate(int fd)
  78. {
  79. /* Rumor has it that some versions of ftruncate do not move the file pointer.
  80. */
  81. if (tor_fd_setpos(fd, 0) < 0)
  82. return -1;
  83. #ifdef _WIN32
  84. return _chsize(fd, 0);
  85. #else
  86. return ftruncate(fd, 0);
  87. #endif
  88. }
  89. /** Minimal version of write_all, for use by logging. */
  90. int
  91. write_all_to_fd_minimal(int fd, const char *buf, size_t count)
  92. {
  93. size_t written = 0;
  94. raw_assert(count < SSIZE_MAX);
  95. while (written < count) {
  96. ssize_t result = write(fd, buf+written, count-written);
  97. if (result<0)
  98. return -1;
  99. written += result;
  100. }
  101. return 0;
  102. }