| 104 | } |
| 105 | |
| 106 | auto FileDescriptorTable::Dup(int old_fd, int new_fd) -> Expected<int> { |
| 107 | if (old_fd < 0 || old_fd >= kMaxFd) { |
| 108 | return std::unexpected(Error(ErrorCode::kFsInvalidFd)); |
| 109 | } |
| 110 | |
| 111 | LockGuard guard(lock_); |
| 112 | |
| 113 | vfs::File* file = table_[old_fd]; |
| 114 | if (file == nullptr) { |
| 115 | return std::unexpected(Error(ErrorCode::kFsInvalidFd)); |
| 116 | } |
| 117 | |
| 118 | if (new_fd >= 0 && new_fd < kMaxFd) { |
| 119 | // 关闭目标 fd 如果已打开 |
| 120 | if (table_[new_fd] != nullptr) { |
| 121 | table_[new_fd] = nullptr; |
| 122 | --open_count_; |
| 123 | } |
| 124 | |
| 125 | table_[new_fd] = file; |
| 126 | ++open_count_; |
| 127 | return new_fd; |
| 128 | } |
| 129 | |
| 130 | // 分配新的 fd |
| 131 | if (new_fd == -1) { |
| 132 | for (int fd = kStderrFd + 1; fd < kMaxFd; ++fd) { |
| 133 | if (table_[fd] == nullptr) { |
| 134 | table_[fd] = file; |
| 135 | ++open_count_; |
| 136 | return fd; |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | return std::unexpected(Error(ErrorCode::kFsFdTableFull)); |
| 142 | } |
| 143 | |
| 144 | auto FileDescriptorTable::CloseAll() -> Expected<void> { |
| 145 | LockGuard guard(lock_); |