posix_file_close.cpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. //
  2. // $Id$
  3. //
  4. #include<__vic/posix/file.h>
  5. #include<__vic/throw_errno.h>
  6. #include<cerrno>
  7. namespace __vic { namespace posix {
  8. //----------------------------------------------------------------------------
  9. void file::close_reset(int &fd)
  10. {
  11. #ifdef __hpux
  12. for(;;)
  13. {
  14. if(::close(fd) == 0) { fd = -1; return; }
  15. int err = errno;
  16. if(err != EINTR)
  17. {
  18. // We can't call close() again in case of EIO because of
  19. // "the state of fildes is unspecified" according to POSIX
  20. fd = -1;
  21. throw_errno("close", err);
  22. }
  23. // Interrupted by signal. Try again
  24. }
  25. #else
  26. int st = ::close(fd);
  27. fd = -1;
  28. if(st == 0) return;
  29. int err = errno;
  30. if(err != EINTR) throw_errno("close", err);
  31. #endif
  32. }
  33. //----------------------------------------------------------------------------
  34. bool file::close_nt(int fd) noexcept
  35. {
  36. // POSIX says that on error the state of fd is unspecified,
  37. // even in case of EINTR
  38. #ifdef __hpux
  39. // Looks like HP-UX is the only OS who made sane behaviour here
  40. for(;;)
  41. {
  42. if(::close(fd) == 0) return true;
  43. if(errno != EINTR) return false;
  44. // Interrupted by signal. Try again
  45. }
  46. #else
  47. // Other OSes including Linux, AIX, *BSD close the fd anyway, even in
  48. // case of EINTR, so repeat call will cause EBADF
  49. return ::close(fd) == 0; //?? || errno == EINTR;
  50. #endif
  51. }
  52. //----------------------------------------------------------------------------
  53. }} // namespace