fd_array.cc revision 13897
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2016 Advanced Micro Devices, Inc.
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only
611308Santhony.gutierrez@amd.com *
711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met:
911308Santhony.gutierrez@amd.com *
1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice,
1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer.
1211308Santhony.gutierrez@amd.com *
1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice,
1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation
1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution.
1611308Santhony.gutierrez@amd.com *
1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its
1811308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from this
1911308Santhony.gutierrez@amd.com * software without specific prior written permission.
2011308Santhony.gutierrez@amd.com *
2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE.
3211308Santhony.gutierrez@amd.com *
3311308Santhony.gutierrez@amd.com * Authors: Brandon Potter
3411308Santhony.gutierrez@amd.com */
3511308Santhony.gutierrez@amd.com
3611308Santhony.gutierrez@amd.com#include "sim/fd_array.hh"
3711308Santhony.gutierrez@amd.com
3811308Santhony.gutierrez@amd.com#include <fcntl.h>
3911308Santhony.gutierrez@amd.com#include <unistd.h>
4011308Santhony.gutierrez@amd.com
4111308Santhony.gutierrez@amd.com#include <array>
4211308Santhony.gutierrez@amd.com#include <memory>
4311308Santhony.gutierrez@amd.com#include <string>
4411308Santhony.gutierrez@amd.com
4511308Santhony.gutierrez@amd.com#include "base/logging.hh"
4611308Santhony.gutierrez@amd.com#include "base/output.hh"
4711308Santhony.gutierrez@amd.com#include "params/Process.hh"
4811308Santhony.gutierrez@amd.com#include "sim/fd_entry.hh"
4911308Santhony.gutierrez@amd.com
5011308Santhony.gutierrez@amd.comFDArray::FDArray(std::string const& input, std::string const& output,
5111308Santhony.gutierrez@amd.com                 std::string const& errout)
5211308Santhony.gutierrez@amd.com    :  _fdArray(), _input(input), _output(output), _errout(errout),
5311308Santhony.gutierrez@amd.com      _imap {{"",       -1},
5411308Santhony.gutierrez@amd.com             {"cin",    STDIN_FILENO},
5511308Santhony.gutierrez@amd.com             {"stdin",  STDIN_FILENO}},
5611308Santhony.gutierrez@amd.com      _oemap{{"",       -1},
5711308Santhony.gutierrez@amd.com             {"cout",   STDOUT_FILENO},
5811308Santhony.gutierrez@amd.com             {"stdout", STDOUT_FILENO},
5911308Santhony.gutierrez@amd.com             {"cerr",   STDERR_FILENO},
6011308Santhony.gutierrez@amd.com             {"stderr", STDERR_FILENO}}
6111308Santhony.gutierrez@amd.com{
6211308Santhony.gutierrez@amd.com    int sim_fd;
6311308Santhony.gutierrez@amd.com    std::map<std::string, int>::iterator it;
6411308Santhony.gutierrez@amd.com
6511308Santhony.gutierrez@amd.com    /**
6611308Santhony.gutierrez@amd.com     * Search through the input options and setup the default fd if match is
6711308Santhony.gutierrez@amd.com     * found; otherwise, open an input file and seek to location.
6811308Santhony.gutierrez@amd.com     */
6911308Santhony.gutierrez@amd.com    if ((it = _imap.find(input)) != _imap.end())
7011308Santhony.gutierrez@amd.com        sim_fd = it->second;
7111308Santhony.gutierrez@amd.com    else
7211308Santhony.gutierrez@amd.com        sim_fd = openInputFile(input);
7311308Santhony.gutierrez@amd.com
7411308Santhony.gutierrez@amd.com    auto ffd = std::make_shared<FileFDEntry>(sim_fd, O_RDONLY, input, false);
7511308Santhony.gutierrez@amd.com    _fdArray[STDIN_FILENO] = ffd;
7611308Santhony.gutierrez@amd.com
7711308Santhony.gutierrez@amd.com    /**
7811308Santhony.gutierrez@amd.com     * Search through the output/error options and setup the default fd if
7911308Santhony.gutierrez@amd.com     * match is found; otherwise, open an output file and seek to location.
8011308Santhony.gutierrez@amd.com     */
8111308Santhony.gutierrez@amd.com    if ((it = _oemap.find(output)) != _oemap.end())
8211308Santhony.gutierrez@amd.com        sim_fd = it->second;
8311308Santhony.gutierrez@amd.com    else
8411308Santhony.gutierrez@amd.com        sim_fd = openOutputFile(output);
8511308Santhony.gutierrez@amd.com
8611308Santhony.gutierrez@amd.com    ffd = std::make_shared<FileFDEntry>(sim_fd, O_WRONLY | O_CREAT | O_TRUNC,
8711697Santhony.gutierrez@amd.com                                        output, false);
8811697Santhony.gutierrez@amd.com    _fdArray[STDOUT_FILENO] = ffd;
8911697Santhony.gutierrez@amd.com
9011697Santhony.gutierrez@amd.com    if (output == errout)
9111697Santhony.gutierrez@amd.com        ; /* Reuse the same file descriptor if these match. */
9211308Santhony.gutierrez@amd.com    else if ((it = _oemap.find(errout)) != _oemap.end())
9311308Santhony.gutierrez@amd.com        sim_fd = it->second;
9411308Santhony.gutierrez@amd.com    else
9511308Santhony.gutierrez@amd.com        sim_fd = openOutputFile(errout);
9611308Santhony.gutierrez@amd.com
9711308Santhony.gutierrez@amd.com    ffd = std::make_shared<FileFDEntry>(sim_fd, O_WRONLY | O_CREAT | O_TRUNC,
9811308Santhony.gutierrez@amd.com                                        errout, false);
9911308Santhony.gutierrez@amd.com    _fdArray[STDERR_FILENO] = ffd;
10011308Santhony.gutierrez@amd.com}
10111308Santhony.gutierrez@amd.com
10211308Santhony.gutierrez@amd.comvoid
10311308Santhony.gutierrez@amd.comFDArray::updateFileOffsets()
10411308Santhony.gutierrez@amd.com{
10511308Santhony.gutierrez@amd.com    for (auto& fdp : _fdArray) {
10611308Santhony.gutierrez@amd.com        /**
10711308Santhony.gutierrez@amd.com         * It only makes sense to check the offsets if the file descriptor
10811308Santhony.gutierrez@amd.com         * type is 'File' (which indicates that this file is backed by a
10911308Santhony.gutierrez@amd.com         * file on the host). If the type is File, then record the offset.
11011308Santhony.gutierrez@amd.com         */
11111308Santhony.gutierrez@amd.com        auto ffd = std::dynamic_pointer_cast<FileFDEntry>(fdp);
11211308Santhony.gutierrez@amd.com
11311308Santhony.gutierrez@amd.com        if (!ffd)
11411308Santhony.gutierrez@amd.com            continue;
11511308Santhony.gutierrez@amd.com
11611308Santhony.gutierrez@amd.com        /**
11711308Santhony.gutierrez@amd.com         * Use lseek with SEEK_CUR with offset 0 to figure out where the
11811308Santhony.gutierrez@amd.com         * offset currently resides and pass that back to our setter.
11911308Santhony.gutierrez@amd.com         */
12011308Santhony.gutierrez@amd.com        int sim_fd = ffd->getSimFD();
12111308Santhony.gutierrez@amd.com        ffd->setFileOffset(lseek(sim_fd, 0, SEEK_CUR));
12211308Santhony.gutierrez@amd.com    }
12311308Santhony.gutierrez@amd.com}
12411308Santhony.gutierrez@amd.com
12511308Santhony.gutierrez@amd.comvoid
12611308Santhony.gutierrez@amd.comFDArray::restoreFileOffsets()
12711308Santhony.gutierrez@amd.com{
12811308Santhony.gutierrez@amd.com    /**
12911697Santhony.gutierrez@amd.com     * Use this lambda to highlight what we mean to do with the seek.
13011308Santhony.gutierrez@amd.com     * Notice that this either seeks correctly (sets the file location on the
13111308Santhony.gutierrez@amd.com     * host) or it fails with a fatal. The error is fatal because it's not
13211308Santhony.gutierrez@amd.com     * possible to guarantee that the simulation will proceed as it should
13311308Santhony.gutierrez@amd.com     * have in the same way that it would have proceeded sans checkpoints.
13411308Santhony.gutierrez@amd.com     */
13511308Santhony.gutierrez@amd.com    auto seek = [] (std::shared_ptr<FileFDEntry> ffd)
13611308Santhony.gutierrez@amd.com    {
13711308Santhony.gutierrez@amd.com        if (lseek(ffd->getSimFD(), ffd->getFileOffset(), SEEK_SET) < 0)
13811308Santhony.gutierrez@amd.com            fatal("Unable to seek to location in %s", ffd->getFileName());
13911308Santhony.gutierrez@amd.com    };
14011308Santhony.gutierrez@amd.com
14111308Santhony.gutierrez@amd.com    std::map<std::string, int>::iterator it;
14211308Santhony.gutierrez@amd.com
14311308Santhony.gutierrez@amd.com    /**
14411308Santhony.gutierrez@amd.com     * Search through the input options and set fd if match is found;
14511308Santhony.gutierrez@amd.com     * otherwise, open an input file and seek to location.
14611308Santhony.gutierrez@amd.com     * Check if user has specified a different input file, and if so, use it
14711308Santhony.gutierrez@amd.com     * instead of the file specified in the checkpoint. This also resets the
14811308Santhony.gutierrez@amd.com     * file offset from the checkpointed value
14911308Santhony.gutierrez@amd.com     */
15011308Santhony.gutierrez@amd.com    std::shared_ptr<FDEntry> stdin_fde = _fdArray[STDIN_FILENO];
15111308Santhony.gutierrez@amd.com    auto stdin_ffd = std::dynamic_pointer_cast<FileFDEntry>(stdin_fde);
15211308Santhony.gutierrez@amd.com
15311308Santhony.gutierrez@amd.com    if (_input != stdin_ffd->getFileName()) {
15411308Santhony.gutierrez@amd.com        warn("Using new input file (%s) rather than checkpointed (%s)\n",
15511308Santhony.gutierrez@amd.com             _input, stdin_ffd->getFileName());
15611308Santhony.gutierrez@amd.com        stdin_ffd->setFileName(_input);
15711308Santhony.gutierrez@amd.com        stdin_ffd->setFileOffset(0);
15811308Santhony.gutierrez@amd.com    }
15911308Santhony.gutierrez@amd.com
16011308Santhony.gutierrez@amd.com    if ((it = _imap.find(stdin_ffd->getFileName())) != _imap.end()) {
16111308Santhony.gutierrez@amd.com        stdin_ffd->setSimFD(it->second);
16211308Santhony.gutierrez@amd.com    } else {
16311308Santhony.gutierrez@amd.com        stdin_ffd->setSimFD(openInputFile(stdin_ffd->getFileName()));
16411308Santhony.gutierrez@amd.com        seek(stdin_ffd);
16511308Santhony.gutierrez@amd.com    }
16611308Santhony.gutierrez@amd.com
16711308Santhony.gutierrez@amd.com    /**
16811308Santhony.gutierrez@amd.com     * Search through the output options and set fd if match is found;
16911308Santhony.gutierrez@amd.com     * otherwise, open an output file and seek to location.
17011308Santhony.gutierrez@amd.com     * Check if user has specified a different output file, and if so, use it
17111308Santhony.gutierrez@amd.com     * instead of the file specified in the checkpoint. This also resets the
17211308Santhony.gutierrez@amd.com     * file offset from the checkpointed value
17311308Santhony.gutierrez@amd.com     */
17411308Santhony.gutierrez@amd.com    std::shared_ptr<FDEntry> stdout_fde = _fdArray[STDOUT_FILENO];
17511308Santhony.gutierrez@amd.com    auto stdout_ffd = std::dynamic_pointer_cast<FileFDEntry>(stdout_fde);
17611308Santhony.gutierrez@amd.com
17711308Santhony.gutierrez@amd.com    if (_output != stdout_ffd->getFileName()) {
17811308Santhony.gutierrez@amd.com        warn("Using new output file (%s) rather than checkpointed (%s)\n",
17911308Santhony.gutierrez@amd.com             _output, stdout_ffd->getFileName());
18011308Santhony.gutierrez@amd.com        stdout_ffd->setFileName(_output);
18111308Santhony.gutierrez@amd.com        stdout_ffd->setFileOffset(0);
18211308Santhony.gutierrez@amd.com    }
18311697Santhony.gutierrez@amd.com
18411697Santhony.gutierrez@amd.com    if ((it = _oemap.find(stdout_ffd->getFileName())) != _oemap.end()) {
18511308Santhony.gutierrez@amd.com        stdout_ffd->setSimFD(it->second);
18611697Santhony.gutierrez@amd.com    } else {
18711308Santhony.gutierrez@amd.com        stdout_ffd->setSimFD(openOutputFile(stdout_ffd->getFileName()));
18811697Santhony.gutierrez@amd.com        seek(stdout_ffd);
18911697Santhony.gutierrez@amd.com    }
19011308Santhony.gutierrez@amd.com
19111308Santhony.gutierrez@amd.com    /**
19211697Santhony.gutierrez@amd.com     * Search through the error options and set fd if match is found;
19311308Santhony.gutierrez@amd.com     * otherwise, open an error file and seek to location.
19411308Santhony.gutierrez@amd.com     * Check if user has specified a different error file, and if so, use it
19511308Santhony.gutierrez@amd.com     * instead of the file specified in the checkpoint. This also resets the
19611308Santhony.gutierrez@amd.com     * file offset from the checkpointed value
19711308Santhony.gutierrez@amd.com     */
19811308Santhony.gutierrez@amd.com    std::shared_ptr<FDEntry> stderr_fde = _fdArray[STDERR_FILENO];
19911308Santhony.gutierrez@amd.com    auto stderr_ffd = std::dynamic_pointer_cast<FileFDEntry>(stderr_fde);
20011308Santhony.gutierrez@amd.com
20111308Santhony.gutierrez@amd.com    if (_errout != stderr_ffd->getFileName()) {
20211308Santhony.gutierrez@amd.com        warn("Using new error file (%s) rather than checkpointed (%s)\n",
20311308Santhony.gutierrez@amd.com             _errout, stderr_ffd->getFileName());
20411308Santhony.gutierrez@amd.com        stderr_ffd->setFileName(_errout);
20511308Santhony.gutierrez@amd.com        stderr_ffd->setFileOffset(0);
20611308Santhony.gutierrez@amd.com    }
20711308Santhony.gutierrez@amd.com
20811308Santhony.gutierrez@amd.com    if (stdout_ffd->getFileName() == stderr_ffd->getFileName()) {
20911308Santhony.gutierrez@amd.com        /* Reuse the same sim_fd file descriptor if these match. */
21011308Santhony.gutierrez@amd.com        stderr_ffd->setSimFD(stdout_ffd->getSimFD());
21111308Santhony.gutierrez@amd.com    } else if ((it = _oemap.find(stderr_ffd->getFileName())) != _oemap.end()) {
21211308Santhony.gutierrez@amd.com        stderr_ffd->setSimFD(it->second);
21311308Santhony.gutierrez@amd.com    } else {
21411308Santhony.gutierrez@amd.com        stderr_ffd->setSimFD(openOutputFile(stderr_ffd->getFileName()));
21511308Santhony.gutierrez@amd.com        seek(stderr_ffd);
21611308Santhony.gutierrez@amd.com    }
21711308Santhony.gutierrez@amd.com
21811308Santhony.gutierrez@amd.com    for (int tgt_fd = 3; tgt_fd < _fdArray.size(); tgt_fd++) {
21911308Santhony.gutierrez@amd.com        std::shared_ptr<FDEntry> fdp = _fdArray[tgt_fd];
22011308Santhony.gutierrez@amd.com        if (!fdp)
22111308Santhony.gutierrez@amd.com            continue;
22211308Santhony.gutierrez@amd.com
22311308Santhony.gutierrez@amd.com        /* Need to reconnect pipe ends. */
22411308Santhony.gutierrez@amd.com        if (auto pfd = std::dynamic_pointer_cast<PipeFDEntry>(fdp)) {
22511308Santhony.gutierrez@amd.com            /**
22611308Santhony.gutierrez@amd.com             * Check which end of the pipe we are looking at; we only want
22711308Santhony.gutierrez@amd.com             * to setup the pipe once so we arbitrarily choose the read
22811308Santhony.gutierrez@amd.com             * end to be the end that sets up the pipe.
22911308Santhony.gutierrez@amd.com             */
23011308Santhony.gutierrez@amd.com            if (pfd->getEndType() == PipeFDEntry::EndType::write)
23111308Santhony.gutierrez@amd.com                continue;
23211308Santhony.gutierrez@amd.com
23311308Santhony.gutierrez@amd.com            /* Setup the pipe or fatal out of the simulation. */
23411308Santhony.gutierrez@amd.com            int fd_pair[2];
23511308Santhony.gutierrez@amd.com            if (pipe(fd_pair) < 0)
23611308Santhony.gutierrez@amd.com                fatal("Unable to create new pipe");
23711308Santhony.gutierrez@amd.com
23811308Santhony.gutierrez@amd.com            /**
23911308Santhony.gutierrez@amd.com             * Reconstruct the ends of the pipe by reassigning the pipe
24011308Santhony.gutierrez@amd.com             * that we created on the host. This one is the read end.
24111308Santhony.gutierrez@amd.com             */
24211308Santhony.gutierrez@amd.com            pfd->setSimFD(fd_pair[0]);
24311308Santhony.gutierrez@amd.com
24411308Santhony.gutierrez@amd.com            /**
24511308Santhony.gutierrez@amd.com             * Grab the write end by referencing the read ends source and
24611308Santhony.gutierrez@amd.com             * using that tgt_fd to index the array.
24711308Santhony.gutierrez@amd.com             */
24811308Santhony.gutierrez@amd.com            int prs = pfd->getPipeReadSource();
24911308Santhony.gutierrez@amd.com            std::shared_ptr<FDEntry> write_fdp = _fdArray[prs];
25011308Santhony.gutierrez@amd.com
25111308Santhony.gutierrez@amd.com            /* Now cast it and make sure that we are still sane. */
25211308Santhony.gutierrez@amd.com            auto write_pfd = std::dynamic_pointer_cast<PipeFDEntry>(write_fdp);
25311308Santhony.gutierrez@amd.com
25411308Santhony.gutierrez@amd.com            /* Hook up the write end back to the right side of the pipe. */
25511308Santhony.gutierrez@amd.com            write_pfd->setSimFD(fd_pair[1]);
25611308Santhony.gutierrez@amd.com        }
25711308Santhony.gutierrez@amd.com
25811308Santhony.gutierrez@amd.com        /* Need to reassign 'driver'. */
25911308Santhony.gutierrez@amd.com        if (auto dfd = std::dynamic_pointer_cast<DeviceFDEntry>(fdp)) {
26011308Santhony.gutierrez@amd.com            /**
26111308Santhony.gutierrez@amd.com             * Yeah, how does one retain the entire driver state from this
26211308Santhony.gutierrez@amd.com             * particular set of code? If you figure it out, add some code
26311308Santhony.gutierrez@amd.com             * here to rectify the issue.
26411308Santhony.gutierrez@amd.com             */
26511308Santhony.gutierrez@amd.com            fatal("Unable to restore checkpoints with emulated drivers");
26611308Santhony.gutierrez@amd.com        }
26711308Santhony.gutierrez@amd.com
26811308Santhony.gutierrez@amd.com        /* Need to open files and seek. */
26911308Santhony.gutierrez@amd.com        if (auto ffd = std::dynamic_pointer_cast<FileFDEntry>(fdp)) {
27011308Santhony.gutierrez@amd.com            /**
27111308Santhony.gutierrez@amd.com             * Assume that this has the mode of an output file so there's no
27211308Santhony.gutierrez@amd.com             * need to worry about properly recording the mode. If you're
27311308Santhony.gutierrez@amd.com             * reading this and this happens to be your issue, at least be
27411308Santhony.gutierrez@amd.com             * happy that you've discovered the issue (and not mad at me).
27511308Santhony.gutierrez@amd.com             * Onward ho!
27611308Santhony.gutierrez@amd.com             */
27711308Santhony.gutierrez@amd.com            int sim_fd = openFile(ffd->getFileName(), ffd->getFlags(), 0664);
27811308Santhony.gutierrez@amd.com            ffd->setSimFD(sim_fd);
27911308Santhony.gutierrez@amd.com            seek(ffd);
28011308Santhony.gutierrez@amd.com        }
28111308Santhony.gutierrez@amd.com    }
28211308Santhony.gutierrez@amd.com}
28311308Santhony.gutierrez@amd.com
28411308Santhony.gutierrez@amd.comint
28511308Santhony.gutierrez@amd.comFDArray::allocFD(std::shared_ptr<FDEntry> in)
28611308Santhony.gutierrez@amd.com{
28711308Santhony.gutierrez@amd.com    for (int i = 0; i < _fdArray.size(); i++) {
28811308Santhony.gutierrez@amd.com        std::shared_ptr<FDEntry> fdp = _fdArray[i];
28911308Santhony.gutierrez@amd.com        if (!fdp) {
29011308Santhony.gutierrez@amd.com            _fdArray[i] = in;
29111308Santhony.gutierrez@amd.com            return i;
29211308Santhony.gutierrez@amd.com        }
29311308Santhony.gutierrez@amd.com    }
29411308Santhony.gutierrez@amd.com    fatal("Out of target file descriptors");
29511308Santhony.gutierrez@amd.com}
29611308Santhony.gutierrez@amd.com
29711308Santhony.gutierrez@amd.comint
29811308Santhony.gutierrez@amd.comFDArray::openFile(std::string const& filename, int flags, mode_t mode) const
29911308Santhony.gutierrez@amd.com{
30011308Santhony.gutierrez@amd.com    int sim_fd = open(filename.c_str(), flags, mode);
30111308Santhony.gutierrez@amd.com    if (sim_fd != -1)
30211308Santhony.gutierrez@amd.com        return sim_fd;
30311308Santhony.gutierrez@amd.com    fatal("Unable to open %s with mode %O", filename, mode);
30411308Santhony.gutierrez@amd.com}
30511308Santhony.gutierrez@amd.com
30611308Santhony.gutierrez@amd.comint
30711308Santhony.gutierrez@amd.comFDArray::openInputFile(std::string const& filename) const
30812603Sgabeblack@google.com{
30912603Sgabeblack@google.com    return openFile(filename, O_RDONLY, 00);
31011308Santhony.gutierrez@amd.com}
31111308Santhony.gutierrez@amd.com
31211308Santhony.gutierrez@amd.comint
31311308Santhony.gutierrez@amd.comFDArray::openOutputFile(std::string const& filename) const
31411308Santhony.gutierrez@amd.com{
31511308Santhony.gutierrez@amd.com    return openFile(simout.resolve(filename),
31611308Santhony.gutierrez@amd.com                    O_WRONLY | O_CREAT | O_TRUNC, 0664);
31711308Santhony.gutierrez@amd.com}
31811308Santhony.gutierrez@amd.com
31911308Santhony.gutierrez@amd.comstd::shared_ptr<FDEntry>
32011308Santhony.gutierrez@amd.comFDArray::getFDEntry(int tgt_fd)
32111308Santhony.gutierrez@amd.com{
32211308Santhony.gutierrez@amd.com    assert(0 <= tgt_fd && tgt_fd < _fdArray.size());
32311308Santhony.gutierrez@amd.com    return _fdArray[tgt_fd];
32411308Santhony.gutierrez@amd.com}
32511308Santhony.gutierrez@amd.com
32611308Santhony.gutierrez@amd.comvoid
32711308Santhony.gutierrez@amd.comFDArray::setFDEntry(int tgt_fd, std::shared_ptr<FDEntry> fdep)
32811308Santhony.gutierrez@amd.com{
32911308Santhony.gutierrez@amd.com    assert(0 <= tgt_fd && tgt_fd < _fdArray.size());
33011308Santhony.gutierrez@amd.com    _fdArray[tgt_fd] = fdep;
33111308Santhony.gutierrez@amd.com}
33211308Santhony.gutierrez@amd.com
33311308Santhony.gutierrez@amd.comint
33411308Santhony.gutierrez@amd.comFDArray::closeFDEntry(int tgt_fd)
33511308Santhony.gutierrez@amd.com{
33612888Sbrandon.potter@amd.com    if (tgt_fd >= _fdArray.size() || tgt_fd < 0)
33711308Santhony.gutierrez@amd.com        return -EBADF;
33811308Santhony.gutierrez@amd.com
33911308Santhony.gutierrez@amd.com    int sim_fd = -1;
34011308Santhony.gutierrez@amd.com    auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>(_fdArray[tgt_fd]);
34111308Santhony.gutierrez@amd.com    if (hbfdp)
34211308Santhony.gutierrez@amd.com        sim_fd = hbfdp->getSimFD();
34311308Santhony.gutierrez@amd.com
34411308Santhony.gutierrez@amd.com    int status = 0;
34511308Santhony.gutierrez@amd.com    if (sim_fd > 2)
34611308Santhony.gutierrez@amd.com        status = close(sim_fd);
34711308Santhony.gutierrez@amd.com
34811308Santhony.gutierrez@amd.com    if (status == 0)
34911308Santhony.gutierrez@amd.com        _fdArray[tgt_fd] = nullptr;
35011308Santhony.gutierrez@amd.com
35111308Santhony.gutierrez@amd.com    return status;
35211308Santhony.gutierrez@amd.com}
35311308Santhony.gutierrez@amd.com