Fcitx
unixfd.cpp
1 /*
2  * SPDX-FileCopyrightText: 2016-2016 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 
8 #include "unixfd.h"
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include <cerrno>
12 #include <stdexcept>
13 #include <utility>
14 
15 #if defined(_WIN32)
16 #include <io.h>
17 #endif
18 
19 namespace fcitx {
20 
21 UnixFD::UnixFD() noexcept = default;
22 UnixFD::UnixFD(int fd) : UnixFD(fd, 0) {}
23 UnixFD::UnixFD(int fd, int min) { set(fd, min); }
24 
25 UnixFD::UnixFD(UnixFD &&other) noexcept {
26  operator=(std::forward<UnixFD>(other));
27 }
28 
29 UnixFD::~UnixFD() noexcept { reset(); }
30 
31 UnixFD &UnixFD::operator=(UnixFD &&other) noexcept {
32  // Close current, move over the other one.
33  using std::swap;
34  reset();
35  swap(fd_, other.fd_);
36  return *this;
37 }
38 
39 bool UnixFD::isValid() const noexcept { return fd_ != -1; }
40 
41 int UnixFD::fd() const noexcept { return fd_; }
42 
43 void UnixFD::give(int fd) noexcept {
44  if (fd == -1) {
45  reset();
46  } else {
47  fd_ = fd;
48  }
49 }
50 
51 void UnixFD::set(int fd, int min) {
52  if (fd == -1) {
53  reset();
54  } else {
55 #if defined(_WIN32)
56  FCITX_UNUSED(min);
57  int nfd = _dup(fd);
58 #else
59  int nfd = ::fcntl(fd, F_DUPFD_CLOEXEC, min);
60 #endif
61  if (nfd == -1) {
62  throw std::runtime_error("Failed to dup file descriptor");
63  }
64 
65  fd_ = nfd;
66  }
67 }
68 
69 void UnixFD::set(int fd) { set(fd, 0); }
70 
71 void UnixFD::reset() noexcept {
72  if (fd_ != -1) {
73  int ret;
74  do {
75  ret = close(fd_);
76  } while (ret == -1 && errno == EINTR);
77  fd_ = -1;
78  }
79 }
80 
81 int UnixFD::release() noexcept {
82  int fd = fd_;
83  fd_ = -1;
84  return fd;
85 }
86 } // namespace fcitx
Class wrap around the unix fd.
Definition: unixfd.h:22
bool isValid() const noexcept
Check if fd is not empty.
Definition: unixfd.cpp:39
Definition: action.cpp:17
UnixFD() noexcept
Create an empty UnixFD.
Utility class to handle unix file decriptor.
int fd() const noexcept
Get the internal fd.
Definition: unixfd.cpp:41
void reset() noexcept
Clear the FD and close it.
Definition: unixfd.cpp:71
void set(int fd)
Set a new FD.
Definition: unixfd.cpp:69
void give(int fd) noexcept
Set a new FD and transfer the ownership to UnixFD.
Definition: unixfd.cpp:43
int release() noexcept
Get the internal fd and release the ownership.
Definition: unixfd.cpp:81