|
29 | 29 | // https://bugzilla.redhat.com/show_bug.cgi?id=165427 |
30 | 30 | // Also needed for SO_PEERCRED. |
31 | 31 | #define _GNU_SOURCE |
| 32 | +#include <exception> |
32 | 33 | #endif |
33 | 34 |
|
34 | 35 | #include <oxt/system_calls.hpp> |
@@ -215,7 +216,7 @@ createUnixServer(const StaticString &filename, unsigned int backlogSize, bool au |
215 | 216 | throw SystemException("Cannot create a Unix socket file descriptor", e); |
216 | 217 | } |
217 | 218 |
|
218 | | - FdGuard guard(fd, file, line, true); |
| 219 | + FdGuard guard(fd, file, line); |
219 | 220 | addr.sun_family = AF_LOCAL; |
220 | 221 | strncpy(addr.sun_path, filename.c_str(), filename.size()); |
221 | 222 | addr.sun_path[filename.size()] = '\0'; |
@@ -306,7 +307,7 @@ createTcpServer(const char *address, unsigned short port, unsigned int backlogSi |
306 | 307 | } |
307 | 308 | // Ignore SO_REUSEADDR error, it's not fatal. |
308 | 309 |
|
309 | | - FdGuard guard(fd, file, line, true); |
| 310 | + FdGuard guard(fd, file, line); |
310 | 311 | if (family == AF_INET) { |
311 | 312 | ret = syscalls::bind(fd, (const struct sockaddr *) &addr.v4, sizeof(struct sockaddr_in)); |
312 | 313 | } else { |
@@ -369,7 +370,7 @@ connectToUnixServer(const StaticString &filename, const char *file, |
369 | 370 | throw SystemException("Cannot create a Unix socket file descriptor", e); |
370 | 371 | } |
371 | 372 |
|
372 | | - FdGuard guard(fd, file, line, true); |
| 373 | + FdGuard guard(fd, file, line); |
373 | 374 | int ret; |
374 | 375 | struct sockaddr_un addr; |
375 | 376 |
|
@@ -656,6 +657,72 @@ NConnect_State::asNTCP_State() { |
656 | 657 | } |
657 | 658 |
|
658 | 659 |
|
| 660 | +/****** Scope guards ******/ |
| 661 | + |
| 662 | +FdGuard::FdGuard(FdGuard &&other) |
| 663 | + : mFd(other.mFd) |
| 664 | +{ |
| 665 | + other.mFd = -1; |
| 666 | +} |
| 667 | + |
| 668 | +FdGuard::FdGuard(int fd, const char *sourceFile, unsigned int sourceLine) |
| 669 | + : mFd(fd) |
| 670 | +{ |
| 671 | + if (mFd != -1 && sourceFile != nullptr) { |
| 672 | + P_LOG_FILE_DESCRIPTOR_OPEN3(fd, sourceFile, sourceLine); |
| 673 | + } |
| 674 | +} |
| 675 | + |
| 676 | +FdGuard::~FdGuard() noexcept(false) { |
| 677 | + if (mFd != -1) { |
| 678 | + try { |
| 679 | + safelyClose(mFd); |
| 680 | + } catch (const std::exception &e) { |
| 681 | + bool uncaughtException = |
| 682 | + #if __cplusplus >= 201703L |
| 683 | + std::uncaught_exceptions() > 0; |
| 684 | + #else |
| 685 | + std::uncaught_exception(); |
| 686 | + #endif |
| 687 | + if (uncaughtException) { |
| 688 | + P_WARN("Error closing file descriptor " << mFd << ": " << e.what()); |
| 689 | + return; |
| 690 | + } else { |
| 691 | + throw e; |
| 692 | + } |
| 693 | + } |
| 694 | + P_LOG_FILE_DESCRIPTOR_CLOSE(mFd); |
| 695 | + } |
| 696 | +} |
| 697 | + |
| 698 | +FdGuard & |
| 699 | +FdGuard::operator=(FdGuard &&other) { |
| 700 | + if (this != &other) { |
| 701 | + if (mFd != -1) { |
| 702 | + safelyClose(mFd); |
| 703 | + P_LOG_FILE_DESCRIPTOR_CLOSE(mFd); |
| 704 | + } |
| 705 | + mFd = other.mFd; |
| 706 | + other.mFd = -1; |
| 707 | + } |
| 708 | + return *this; |
| 709 | +} |
| 710 | + |
| 711 | +void |
| 712 | +FdGuard::clear() noexcept { |
| 713 | + mFd = -1; |
| 714 | +} |
| 715 | + |
| 716 | +void |
| 717 | +FdGuard::runNow() noexcept(false) { |
| 718 | + if (mFd != -1) { |
| 719 | + safelyClose(mFd); |
| 720 | + P_LOG_FILE_DESCRIPTOR_CLOSE(mFd); |
| 721 | + mFd = -1; |
| 722 | + } |
| 723 | +} |
| 724 | + |
| 725 | + |
659 | 726 | /****** Other ******/ |
660 | 727 |
|
661 | 728 | bool |
|
0 commit comments