1/*
2 * Copyright (c) 2016 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * For use for simulation and test purposes only
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Authors: Brandon Potter
34 */
35
36#ifndef __FD_ARRAY_HH__
37#define __FD_ARRAY_HH__
38
39#include <array>
40#include <memory>
41#include <string>
42
43#include "sim/fd_entry.hh"
44
45class FDArray
46{
47  public:
48    /**
49     * Initialize the file descriptor array and set the standard file
50     * descriptors to defaults or values passed in with the process
51     * params.
52     * @param input Used to initialize the stdin file descriptor
53     * @param output Used to initialize the stdout file descriptor
54     * @param errout Used to initialize the stderr file descriptor
55     */
56    FDArray(std::string const& input, std::string const& output,
57            std::string const& errout);
58
59    /**
60     * Figure out the file offsets for all currently open files and save them
61     * the offsets during the calls to drain by the owning process.
62     */
63    void updateFileOffsets();
64
65    /**
66     * Restore all offsets for currently open files during the unserialize
67     * phase for the owning process class.
68     */
69    void restoreFileOffsets();
70
71    /**
72     * Put the pointer specified by fdep into the _fdArray entry indexed
73     * by tgt_fd.
74     * @param tgt_fd Use target file descriptors to index the array.
75     * @param fdep Incoming pointer used to set the entry pointed to by tgt_fd.
76     */
77    void setFDEntry(int tgt_fd, std::shared_ptr<FDEntry> fdep);
78
79    /**
80     * Treat this object like a normal array in using the subscript operator
81     * to pull entries out of it.
82     * @param tgt_fd Use target file descriptors to index the array.
83     */
84    std::shared_ptr<FDEntry>
85    operator[](int tgt_fd)
86    {
87        return getFDEntry(tgt_fd);
88    }
89
90    /**
91     * Return the size of the _fdArray field
92     */
93    int getSize() const { return _fdArray.size(); }
94
95    /**
96     * Step through the file descriptor array and find the first available
97     * entry which is denoted as being free by being a 'nullptr'. That file
98     * descriptor entry is the new target file descriptor entry that we
99     * return as the return parameter.
100     * @param fdp Allocated beforehand and passed into this method;
101     * the fdp is meant to be a generic pointer capable of pointing to
102     * different types of file descriptors. Must cast the pointer to the
103     * correct type before dereferencing to access the needed fields.
104     */
105    int allocFD(std::shared_ptr<FDEntry> fdp);
106
107    /**
108     * Try to close the host file descriptor. If successful, set the
109     * specified file descriptor entry object pointer to nullptr.
110     * Used to "close" the target file descriptor.
111     * @param tgt_fd Use target file descriptors to index the array.
112     */
113    int closeFDEntry(int tgt_fd);
114
115  private:
116    /**
117     * Help clarify our intention when opening files in the init and
118     * restoration code. These are helper functions which are not meant to
119     * be exposed to other objects or files.
120     */
121    int openFile(std::string const& file_name, int flags, mode_t mode) const;
122    int openInputFile(std::string const& file_name) const;
123    int openOutputFile(std::string const& file_name) const;
124
125    /**
126     * Return the file descriptor entry object associated with the index
127     * provided. (The index is protected with bounds checking on the array
128     * size without the use of the array's at operator.)
129     * @param tgt_fd Use target file descriptors to index the array.
130     */
131    std::shared_ptr<FDEntry> getFDEntry(int tgt_fd);
132
133    /**
134     * Hold pointers to the file descriptor entries. The array size is
135     * statically defined by the operating system.
136     */
137    static constexpr size_t _numFDs {1024};
138    std::array<std::shared_ptr<FDEntry>, _numFDs> _fdArray;
139
140    /**
141     * Hold param strings passed from the Process class which indicate
142     * the filename for each of the corresponding files or some keyword
143     * indicating the use of standard file descriptors.
144     */
145    std::string _input;
146    std::string _output;
147    std::string _errout;
148
149    /**
150     * Hold strings which represent the default values which are checked
151     * against to initialize the standard file descriptors. If the string
152     * provided doesn't hit against these maps, then a file is opened on the
153     * host instead of using the host's standard file descriptors.
154     */
155    std::map<std::string, int> _imap;
156    std::map<std::string, int> _oemap;
157};
158
159#endif // __FD_ARRAY_HH__
160