fdio.c 2.5 KB

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