fdio.c 2.4 KB

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