fd_array.cc revision 12697
111856Sbrandon.potter@amd.com/* 211856Sbrandon.potter@amd.com * Copyright (c) 2016 Advanced Micro Devices, Inc. 311856Sbrandon.potter@amd.com * All rights reserved. 411856Sbrandon.potter@amd.com * 511856Sbrandon.potter@amd.com * For use for simulation and test purposes only 611856Sbrandon.potter@amd.com * 711856Sbrandon.potter@amd.com * Redistribution and use in source and binary forms, with or without 811856Sbrandon.potter@amd.com * modification, are permitted provided that the following conditions are met: 911856Sbrandon.potter@amd.com * 1011856Sbrandon.potter@amd.com * 1. Redistributions of source code must retain the above copyright notice, 1111856Sbrandon.potter@amd.com * this list of conditions and the following disclaimer. 1211856Sbrandon.potter@amd.com * 1311856Sbrandon.potter@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice, 1411856Sbrandon.potter@amd.com * this list of conditions and the following disclaimer in the documentation 1511856Sbrandon.potter@amd.com * and/or other materials provided with the distribution. 1611856Sbrandon.potter@amd.com * 1711856Sbrandon.potter@amd.com * 3. Neither the name of the copyright holder nor the names of its 1811856Sbrandon.potter@amd.com * contributors may be used to endorse or promote products derived from this 1911856Sbrandon.potter@amd.com * software without specific prior written permission. 2011856Sbrandon.potter@amd.com * 2111856Sbrandon.potter@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2211856Sbrandon.potter@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311856Sbrandon.potter@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411856Sbrandon.potter@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2511856Sbrandon.potter@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2611856Sbrandon.potter@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2711856Sbrandon.potter@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2811856Sbrandon.potter@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2911856Sbrandon.potter@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3011856Sbrandon.potter@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3111856Sbrandon.potter@amd.com * POSSIBILITY OF SUCH DAMAGE. 3211856Sbrandon.potter@amd.com * 3312697Santhony.gutierrez@amd.com * Authors: Brandon Potter 3411856Sbrandon.potter@amd.com */ 3511856Sbrandon.potter@amd.com 3611856Sbrandon.potter@amd.com#include "sim/fd_array.hh" 3711856Sbrandon.potter@amd.com 3811856Sbrandon.potter@amd.com#include <fcntl.h> 3911856Sbrandon.potter@amd.com#include <unistd.h> 4011856Sbrandon.potter@amd.com 4111856Sbrandon.potter@amd.com#include <array> 4211856Sbrandon.potter@amd.com#include <memory> 4311856Sbrandon.potter@amd.com#include <string> 4411856Sbrandon.potter@amd.com 4512334Sgabeblack@google.com#include "base/logging.hh" 4611856Sbrandon.potter@amd.com#include "params/Process.hh" 4711856Sbrandon.potter@amd.com#include "sim/fd_entry.hh" 4811856Sbrandon.potter@amd.com 4911856Sbrandon.potter@amd.comFDArray::FDArray(std::string const& input, std::string const& output, 5011856Sbrandon.potter@amd.com std::string const& errout) 5111856Sbrandon.potter@amd.com : _input(input), _output(output), _errout(errout), _fdArray(), 5211856Sbrandon.potter@amd.com imap {{"", -1}, 5311856Sbrandon.potter@amd.com {"cin", STDIN_FILENO}, 5411856Sbrandon.potter@amd.com {"stdin", STDIN_FILENO}}, 5511856Sbrandon.potter@amd.com oemap{{"", -1}, 5611856Sbrandon.potter@amd.com {"cout", STDOUT_FILENO}, 5711856Sbrandon.potter@amd.com {"stdout", STDOUT_FILENO}, 5811856Sbrandon.potter@amd.com {"cerr", STDERR_FILENO}, 5911856Sbrandon.potter@amd.com {"stderr", STDERR_FILENO}} 6011856Sbrandon.potter@amd.com{ 6111856Sbrandon.potter@amd.com int sim_fd; 6211856Sbrandon.potter@amd.com std::map<std::string, int>::iterator it; 6311856Sbrandon.potter@amd.com 6411856Sbrandon.potter@amd.com /** 6511856Sbrandon.potter@amd.com * Search through the input options and setup the default fd if match is 6611856Sbrandon.potter@amd.com * found; otherwise, open an input file and seek to location. 6711856Sbrandon.potter@amd.com */ 6811856Sbrandon.potter@amd.com if ((it = imap.find(input)) != imap.end()) 6911856Sbrandon.potter@amd.com sim_fd = it->second; 7011856Sbrandon.potter@amd.com else 7111856Sbrandon.potter@amd.com sim_fd = openInputFile(input); 7211856Sbrandon.potter@amd.com 7311856Sbrandon.potter@amd.com auto ffd = std::make_shared<FileFDEntry>(sim_fd, O_RDONLY, input, false); 7411856Sbrandon.potter@amd.com _fdArray[STDIN_FILENO] = ffd; 7511856Sbrandon.potter@amd.com 7611856Sbrandon.potter@amd.com /** 7711856Sbrandon.potter@amd.com * Search through the output/error options and setup the default fd if 7811856Sbrandon.potter@amd.com * match is found; otherwise, open an output file and seek to location. 7911856Sbrandon.potter@amd.com */ 8011856Sbrandon.potter@amd.com if ((it = oemap.find(output)) != oemap.end()) 8111856Sbrandon.potter@amd.com sim_fd = it->second; 8211856Sbrandon.potter@amd.com else 8311856Sbrandon.potter@amd.com sim_fd = openOutputFile(output); 8411856Sbrandon.potter@amd.com 8511856Sbrandon.potter@amd.com ffd = std::make_shared<FileFDEntry>(sim_fd, O_WRONLY | O_CREAT | O_TRUNC, 8611856Sbrandon.potter@amd.com output, false); 8711856Sbrandon.potter@amd.com _fdArray[STDOUT_FILENO] = ffd; 8811856Sbrandon.potter@amd.com 8911856Sbrandon.potter@amd.com if (output == errout) 9011856Sbrandon.potter@amd.com ; /* Reuse the same file descriptor if these match. */ 9111856Sbrandon.potter@amd.com else if ((it = oemap.find(errout)) != oemap.end()) 9211856Sbrandon.potter@amd.com sim_fd = it->second; 9311856Sbrandon.potter@amd.com else 9411856Sbrandon.potter@amd.com sim_fd = openOutputFile(errout); 9511856Sbrandon.potter@amd.com 9611856Sbrandon.potter@amd.com ffd = std::make_shared<FileFDEntry>(sim_fd, O_WRONLY | O_CREAT | O_TRUNC, 9711856Sbrandon.potter@amd.com errout, false); 9811856Sbrandon.potter@amd.com _fdArray[STDERR_FILENO] = ffd; 9911856Sbrandon.potter@amd.com} 10011856Sbrandon.potter@amd.com 10111856Sbrandon.potter@amd.comvoid 10211856Sbrandon.potter@amd.comFDArray::updateFileOffsets() 10311856Sbrandon.potter@amd.com{ 10411856Sbrandon.potter@amd.com for (auto& fdp : _fdArray) { 10511856Sbrandon.potter@amd.com /** 10611856Sbrandon.potter@amd.com * It only makes sense to check the offsets if the file descriptor 10711856Sbrandon.potter@amd.com * type is 'File' (which indicates that this file is backed by a 10811856Sbrandon.potter@amd.com * file on the host). If the type is File, then record the offset. 10911856Sbrandon.potter@amd.com */ 11011856Sbrandon.potter@amd.com auto ffd = std::dynamic_pointer_cast<FileFDEntry>(fdp); 11111856Sbrandon.potter@amd.com 11211856Sbrandon.potter@amd.com if (!ffd) 11311856Sbrandon.potter@amd.com continue; 11411856Sbrandon.potter@amd.com 11511856Sbrandon.potter@amd.com /** 11611856Sbrandon.potter@amd.com * Use lseek with SEEK_CUR with offset 0 to figure out where the 11711856Sbrandon.potter@amd.com * offset currently resides and pass that back to our setter. 11811856Sbrandon.potter@amd.com */ 11911856Sbrandon.potter@amd.com int sim_fd = ffd->getSimFD(); 12011856Sbrandon.potter@amd.com ffd->setFileOffset(lseek(sim_fd, 0, SEEK_CUR)); 12111856Sbrandon.potter@amd.com } 12211856Sbrandon.potter@amd.com} 12311856Sbrandon.potter@amd.com 12411856Sbrandon.potter@amd.comvoid 12511856Sbrandon.potter@amd.comFDArray::restoreFileOffsets() 12611856Sbrandon.potter@amd.com{ 12711856Sbrandon.potter@amd.com /** 12811856Sbrandon.potter@amd.com * Use this lambda to highlight what we mean to do with the seek. 12911856Sbrandon.potter@amd.com * Notice that this either seeks correctly (sets the file location on the 13011856Sbrandon.potter@amd.com * host) or it fails with a fatal. The error is fatal because it's not 13111856Sbrandon.potter@amd.com * possible to guarantee that the simulation will proceed as it should 13211856Sbrandon.potter@amd.com * have in the same way that it would have proceeded sans checkpoints. 13311856Sbrandon.potter@amd.com */ 13412392Sjason@lowepower.com auto seek = [] (std::shared_ptr<FileFDEntry> ffd) 13511856Sbrandon.potter@amd.com { 13611856Sbrandon.potter@amd.com if (lseek(ffd->getSimFD(), ffd->getFileOffset(), SEEK_SET) < 0) 13711856Sbrandon.potter@amd.com fatal("Unable to seek to location in %s", ffd->getFileName()); 13811856Sbrandon.potter@amd.com }; 13911856Sbrandon.potter@amd.com 14011856Sbrandon.potter@amd.com std::map<std::string, int>::iterator it; 14111856Sbrandon.potter@amd.com 14211856Sbrandon.potter@amd.com /** 14311856Sbrandon.potter@amd.com * Search through the input options and set fd if match is found; 14411856Sbrandon.potter@amd.com * otherwise, open an input file and seek to location. 14511856Sbrandon.potter@amd.com * Check if user has specified a different input file, and if so, use it 14611856Sbrandon.potter@amd.com * instead of the file specified in the checkpoint. This also resets the 14711856Sbrandon.potter@amd.com * file offset from the checkpointed value 14811856Sbrandon.potter@amd.com */ 14911856Sbrandon.potter@amd.com std::shared_ptr<FDEntry> stdin_fde = _fdArray[STDIN_FILENO]; 15011856Sbrandon.potter@amd.com auto stdin_ffd = std::dynamic_pointer_cast<FileFDEntry>(stdin_fde); 15111856Sbrandon.potter@amd.com 15211856Sbrandon.potter@amd.com if (_input != stdin_ffd->getFileName()) { 15311856Sbrandon.potter@amd.com warn("Using new input file (%s) rather than checkpointed (%s)\n", 15411856Sbrandon.potter@amd.com _input, stdin_ffd->getFileName()); 15511856Sbrandon.potter@amd.com stdin_ffd->setFileName(_input); 15611856Sbrandon.potter@amd.com stdin_ffd->setFileOffset(0); 15711856Sbrandon.potter@amd.com } 15811856Sbrandon.potter@amd.com 15911856Sbrandon.potter@amd.com if ((it = imap.find(stdin_ffd->getFileName())) != imap.end()) { 16011856Sbrandon.potter@amd.com stdin_ffd->setSimFD(it->second); 16111856Sbrandon.potter@amd.com } else { 16211856Sbrandon.potter@amd.com stdin_ffd->setSimFD(openInputFile(stdin_ffd->getFileName())); 16311856Sbrandon.potter@amd.com seek(stdin_ffd); 16411856Sbrandon.potter@amd.com } 16511856Sbrandon.potter@amd.com 16611856Sbrandon.potter@amd.com /** 16711856Sbrandon.potter@amd.com * Search through the output options and set fd if match is found; 16811856Sbrandon.potter@amd.com * otherwise, open an output file and seek to location. 16911856Sbrandon.potter@amd.com * Check if user has specified a different output file, and if so, use it 17011856Sbrandon.potter@amd.com * instead of the file specified in the checkpoint. This also resets the 17111856Sbrandon.potter@amd.com * file offset from the checkpointed value 17211856Sbrandon.potter@amd.com */ 17311856Sbrandon.potter@amd.com std::shared_ptr<FDEntry> stdout_fde = _fdArray[STDOUT_FILENO]; 17411856Sbrandon.potter@amd.com auto stdout_ffd = std::dynamic_pointer_cast<FileFDEntry>(stdout_fde); 17511856Sbrandon.potter@amd.com 17611856Sbrandon.potter@amd.com if (_output != stdout_ffd->getFileName()) { 17711856Sbrandon.potter@amd.com warn("Using new output file (%s) rather than checkpointed (%s)\n", 17811856Sbrandon.potter@amd.com _output, stdout_ffd->getFileName()); 17911856Sbrandon.potter@amd.com stdout_ffd->setFileName(_output); 18011856Sbrandon.potter@amd.com stdout_ffd->setFileOffset(0); 18111856Sbrandon.potter@amd.com } 18211856Sbrandon.potter@amd.com 18311856Sbrandon.potter@amd.com if ((it = oemap.find(stdout_ffd->getFileName())) != oemap.end()) { 18411856Sbrandon.potter@amd.com stdout_ffd->setSimFD(it->second); 18511856Sbrandon.potter@amd.com } else { 18611856Sbrandon.potter@amd.com stdout_ffd->setSimFD(openOutputFile(stdout_ffd->getFileName())); 18711856Sbrandon.potter@amd.com seek(stdout_ffd); 18811856Sbrandon.potter@amd.com } 18911856Sbrandon.potter@amd.com 19011856Sbrandon.potter@amd.com /** 19111856Sbrandon.potter@amd.com * Search through the error options and set fd if match is found; 19211856Sbrandon.potter@amd.com * otherwise, open an error file and seek to location. 19311856Sbrandon.potter@amd.com * Check if user has specified a different error file, and if so, use it 19411856Sbrandon.potter@amd.com * instead of the file specified in the checkpoint. This also resets the 19511856Sbrandon.potter@amd.com * file offset from the checkpointed value 19611856Sbrandon.potter@amd.com */ 19711856Sbrandon.potter@amd.com std::shared_ptr<FDEntry> stderr_fde = _fdArray[STDERR_FILENO]; 19811856Sbrandon.potter@amd.com auto stderr_ffd = std::dynamic_pointer_cast<FileFDEntry>(stderr_fde); 19911856Sbrandon.potter@amd.com 20011856Sbrandon.potter@amd.com if (_errout != stderr_ffd->getFileName()) { 20111856Sbrandon.potter@amd.com warn("Using new error file (%s) rather than checkpointed (%s)\n", 20211856Sbrandon.potter@amd.com _errout, stderr_ffd->getFileName()); 20311856Sbrandon.potter@amd.com stderr_ffd->setFileName(_errout); 20411856Sbrandon.potter@amd.com stderr_ffd->setFileOffset(0); 20511856Sbrandon.potter@amd.com } 20611856Sbrandon.potter@amd.com 20711856Sbrandon.potter@amd.com if (stdout_ffd->getFileName() == stderr_ffd->getFileName()) { 20811856Sbrandon.potter@amd.com /* Reuse the same sim_fd file descriptor if these match. */ 20911856Sbrandon.potter@amd.com stderr_ffd->setSimFD(stdout_ffd->getSimFD()); 21011856Sbrandon.potter@amd.com } else if ((it = oemap.find(stderr_ffd->getFileName())) != oemap.end()) { 21111856Sbrandon.potter@amd.com stderr_ffd->setSimFD(it->second); 21211856Sbrandon.potter@amd.com } else { 21311856Sbrandon.potter@amd.com stderr_ffd->setSimFD(openOutputFile(stderr_ffd->getFileName())); 21411856Sbrandon.potter@amd.com seek(stderr_ffd); 21511856Sbrandon.potter@amd.com } 21611856Sbrandon.potter@amd.com 21711856Sbrandon.potter@amd.com for (int tgt_fd = 3; tgt_fd < _fdArray.size(); tgt_fd++) { 21811856Sbrandon.potter@amd.com std::shared_ptr<FDEntry> fdp = _fdArray[tgt_fd]; 21911856Sbrandon.potter@amd.com if (!fdp) 22011856Sbrandon.potter@amd.com continue; 22111856Sbrandon.potter@amd.com 22211856Sbrandon.potter@amd.com /* Need to reconnect pipe ends. */ 22311856Sbrandon.potter@amd.com if (auto pfd = std::dynamic_pointer_cast<PipeFDEntry>(fdp)) { 22411856Sbrandon.potter@amd.com /** 22511856Sbrandon.potter@amd.com * Check which end of the pipe we are looking at; we only want 22611856Sbrandon.potter@amd.com * to setup the pipe once so we arbitrarily choose the read 22711856Sbrandon.potter@amd.com * end to be the end that sets up the pipe. 22811856Sbrandon.potter@amd.com */ 22911856Sbrandon.potter@amd.com if (pfd->getEndType() == PipeFDEntry::EndType::write) 23011856Sbrandon.potter@amd.com continue; 23111856Sbrandon.potter@amd.com 23211856Sbrandon.potter@amd.com /* Setup the pipe or fatal out of the simulation. */ 23311856Sbrandon.potter@amd.com int fd_pair[2]; 23411856Sbrandon.potter@amd.com if (pipe(fd_pair) < 0) 23511856Sbrandon.potter@amd.com fatal("Unable to create new pipe"); 23611856Sbrandon.potter@amd.com 23711856Sbrandon.potter@amd.com /** 23811856Sbrandon.potter@amd.com * Reconstruct the ends of the pipe by reassigning the pipe 23911856Sbrandon.potter@amd.com * that we created on the host. This one is the read end. 24011856Sbrandon.potter@amd.com */ 24111856Sbrandon.potter@amd.com pfd->setSimFD(fd_pair[0]); 24211856Sbrandon.potter@amd.com 24311856Sbrandon.potter@amd.com /** 24411856Sbrandon.potter@amd.com * Grab the write end by referencing the read ends source and 24511856Sbrandon.potter@amd.com * using that tgt_fd to index the array. 24611856Sbrandon.potter@amd.com */ 24711856Sbrandon.potter@amd.com int prs = pfd->getPipeReadSource(); 24811856Sbrandon.potter@amd.com std::shared_ptr<FDEntry> write_fdp = _fdArray[prs]; 24911856Sbrandon.potter@amd.com 25011856Sbrandon.potter@amd.com /* Now cast it and make sure that we are still sane. */ 25111856Sbrandon.potter@amd.com auto write_pfd = std::dynamic_pointer_cast<PipeFDEntry>(write_fdp); 25211856Sbrandon.potter@amd.com 25311856Sbrandon.potter@amd.com /* Hook up the write end back to the right side of the pipe. */ 25411856Sbrandon.potter@amd.com write_pfd->setSimFD(fd_pair[1]); 25511856Sbrandon.potter@amd.com } 25611856Sbrandon.potter@amd.com 25711856Sbrandon.potter@amd.com /* Need to reassign 'driver'. */ 25811856Sbrandon.potter@amd.com if (auto dfd = std::dynamic_pointer_cast<DeviceFDEntry>(fdp)) { 25911856Sbrandon.potter@amd.com /** 26011856Sbrandon.potter@amd.com * Yeah, how does one retain the entire driver state from this 26111856Sbrandon.potter@amd.com * particular set of code? If you figure it out, add some code 26211856Sbrandon.potter@amd.com * here to rectify the issue. 26311856Sbrandon.potter@amd.com */ 26411856Sbrandon.potter@amd.com fatal("Unable to restore checkpoints with emulated drivers"); 26511856Sbrandon.potter@amd.com } 26611856Sbrandon.potter@amd.com 26711856Sbrandon.potter@amd.com /* Need to open files and seek. */ 26811856Sbrandon.potter@amd.com if (auto ffd = std::dynamic_pointer_cast<FileFDEntry>(fdp)) { 26911856Sbrandon.potter@amd.com /** 27011856Sbrandon.potter@amd.com * Assume that this has the mode of an output file so there's no 27111856Sbrandon.potter@amd.com * need to worry about properly recording the mode. If you're 27211856Sbrandon.potter@amd.com * reading this and this happens to be your issue, at least be 27311856Sbrandon.potter@amd.com * happy that you've discovered the issue (and not mad at me). 27411856Sbrandon.potter@amd.com * Onward ho! 27511856Sbrandon.potter@amd.com */ 27611856Sbrandon.potter@amd.com int sim_fd = openFile(ffd->getFileName(), ffd->getFlags(), 0664); 27711856Sbrandon.potter@amd.com ffd->setSimFD(sim_fd); 27811856Sbrandon.potter@amd.com seek(ffd); 27911856Sbrandon.potter@amd.com } 28011856Sbrandon.potter@amd.com } 28111856Sbrandon.potter@amd.com} 28211856Sbrandon.potter@amd.com 28311856Sbrandon.potter@amd.comint 28411856Sbrandon.potter@amd.comFDArray::allocFD(std::shared_ptr<FDEntry> in) 28511856Sbrandon.potter@amd.com{ 28611856Sbrandon.potter@amd.com for (int i = 0; i < _fdArray.size(); i++) { 28711856Sbrandon.potter@amd.com std::shared_ptr<FDEntry> fdp = _fdArray[i]; 28811856Sbrandon.potter@amd.com if (!fdp) { 28911856Sbrandon.potter@amd.com _fdArray[i] = in; 29011856Sbrandon.potter@amd.com return i; 29111856Sbrandon.potter@amd.com } 29211856Sbrandon.potter@amd.com } 29311856Sbrandon.potter@amd.com fatal("Out of target file descriptors"); 29411856Sbrandon.potter@amd.com} 29511856Sbrandon.potter@amd.com 29611856Sbrandon.potter@amd.comint 29711856Sbrandon.potter@amd.comFDArray::openFile(std::string const& filename, int flags, mode_t mode) const 29811856Sbrandon.potter@amd.com{ 29911856Sbrandon.potter@amd.com int sim_fd = open(filename.c_str(), flags, mode); 30011856Sbrandon.potter@amd.com if (sim_fd != -1) 30111856Sbrandon.potter@amd.com return sim_fd; 30211856Sbrandon.potter@amd.com fatal("Unable to open %s with mode %O", filename, mode); 30311856Sbrandon.potter@amd.com} 30411856Sbrandon.potter@amd.com 30511856Sbrandon.potter@amd.comint 30611856Sbrandon.potter@amd.comFDArray::openInputFile(std::string const& filename) const 30711856Sbrandon.potter@amd.com{ 30811856Sbrandon.potter@amd.com return openFile(filename, O_RDONLY, 00); 30911856Sbrandon.potter@amd.com} 31011856Sbrandon.potter@amd.com 31111856Sbrandon.potter@amd.comint 31211856Sbrandon.potter@amd.comFDArray::openOutputFile(std::string const& filename) const 31311856Sbrandon.potter@amd.com{ 31411856Sbrandon.potter@amd.com return openFile(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664); 31511856Sbrandon.potter@amd.com} 31611856Sbrandon.potter@amd.com 31711856Sbrandon.potter@amd.comstd::shared_ptr<FDEntry> 31811856Sbrandon.potter@amd.comFDArray::getFDEntry(int tgt_fd) 31911856Sbrandon.potter@amd.com{ 32011856Sbrandon.potter@amd.com assert(0 <= tgt_fd && tgt_fd < _fdArray.size()); 32111856Sbrandon.potter@amd.com return _fdArray[tgt_fd]; 32211856Sbrandon.potter@amd.com} 32311856Sbrandon.potter@amd.com 32411886Sbrandon.potter@amd.comvoid 32511886Sbrandon.potter@amd.comFDArray::setFDEntry(int tgt_fd, std::shared_ptr<FDEntry> fdep) 32611886Sbrandon.potter@amd.com{ 32711886Sbrandon.potter@amd.com assert(0 <= tgt_fd && tgt_fd < _fdArray.size()); 32811886Sbrandon.potter@amd.com _fdArray[tgt_fd] = fdep; 32911886Sbrandon.potter@amd.com} 33011886Sbrandon.potter@amd.com 33111856Sbrandon.potter@amd.comint 33211856Sbrandon.potter@amd.comFDArray::closeFDEntry(int tgt_fd) 33311856Sbrandon.potter@amd.com{ 33411856Sbrandon.potter@amd.com if (tgt_fd >= _fdArray.size() || tgt_fd < 0) 33511856Sbrandon.potter@amd.com return -EBADF; 33611856Sbrandon.potter@amd.com 33711856Sbrandon.potter@amd.com int sim_fd = -1; 33811856Sbrandon.potter@amd.com auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>(_fdArray[tgt_fd]); 33911856Sbrandon.potter@amd.com if (hbfdp) 34011856Sbrandon.potter@amd.com sim_fd = hbfdp->getSimFD(); 34111856Sbrandon.potter@amd.com 34211856Sbrandon.potter@amd.com int status = 0; 34311856Sbrandon.potter@amd.com if (sim_fd > 2) 34411856Sbrandon.potter@amd.com status = close(sim_fd); 34511856Sbrandon.potter@amd.com 34611856Sbrandon.potter@amd.com if (status == 0) 34711856Sbrandon.potter@amd.com _fdArray[tgt_fd] = nullptr; 34811856Sbrandon.potter@amd.com 34911856Sbrandon.potter@amd.com return status; 35011856Sbrandon.potter@amd.com} 351