summaryrefslogtreecommitdiff
path: root/include/mts/MTS_System.h
blob: 24dc61623264408289bcd7c6ec0ee46bcdbf0cdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
 * Copyright (C) 2015 by Multi-Tech Systems
 *
 * This file is part of libmts.
 *
 * libmts is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * libmts is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with libmts.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/*! \file   MTS_System.h
 \brief  System Utilities
 \date   15JUN11
 \author Sean Godinez

 System utilities for time, endian, etc.
 */
#ifndef MTS_SYSTEM_H
#define MTS_SYSTEM_H

#include <mts/MTS_NonConstructable.h>
#include <mts/MTS_Stdint.h>
#include <string>
#include <vector>

namespace MTS {

    class System: private NonConstructable {

        public:

            //! Type of the pipe to be opened in executeBackground
            enum class PipeType {
                READ, WRITE
            };

            //! Utility structure with information about the child process
            struct ChildHandle {
                pid_t pid;
                FILE* stream;
            };

            //UTC (Coordinated Universal Time) : This is the standard international time or the Greenwich Mean Time.
            //EPOCH : number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time.

            static uint64_t timeMicros();
            static uint64_t precisionTimeMicros();

            //MONOTONIC : number of seconds elapsed since some unspecified starting point. When time is changed by user, timer are unaffected.

            static uint64_t monoTimeMicros();

            static bool isBigEndian();
            static void swapBytes(uint8_t* const pBuffer, const uint32_t iSize);

            static int32_t cmd(const std::string& cmd, std::string& result);
            static int32_t readFile(const std::string& path, std::string& result);

            //! Execute application with specified arguments.
            /*!
             * A safer alternative to System::cmd that allows to execute applications with controlled
             * list of arguments bypasing the system shell.
             *
             * \param  cmd    name of the application to be executed
             * \param  argv   vector of arguments (excluding argument zero)
             * \param  result stdout output from the application is stored here
             * \return result code as for std::system and UNIX pclose
             */
            static int32_t execute(const std::string& cmd, const std::vector<std::string>& argv, std::string& result);

            //! Execute application with specified arguments and environment variables inheritance.
            /*!
             * A safer alternative to System::cmd that allows to execute applications with controlled
             * list of arguments and inherited environment variables bypasing the system shell.
             *
             * \param  cmd    name of the application to be executed
             * \param  argv   vector of arguments (excluding argument zero)
             * \param  result stdout output from the application is stored here
             * \return result code as for std::system and UNIX pclose
             */
            static int32_t executeEnv(const std::string& cmd, const std::vector<std::string>& argv, std::string& result);

            //! Spawn a process and open pipe with the specified type (READ or WRITE)
            /*!
            * A safer alternative to POSIX popen that allows to execute applications with controlled
            * list of arguments bypasing the system shell. If succeded, information about the spawned
            * process is written to the \p child structure.
            *
            * \param  cmd   name of the application to be executed
            * \param  argv  vector of arguments (excluding argument zero)
            * \param  type  open pipe for read from child or write to child
            * \param  child on success is populated with child process information, on failure is not defined
            * \return true  on success, false on failure
            */
            static bool executeBackground(const std::string& cmd, const std::vector<std::string>& argv, PipeType type, ChildHandle& child);

            //! Spawn a process and open pipe with the specified type (READ or WRITE)
            /*!
            * A safer alternative to POSIX popen that allows to execute applications with controlled
            * list of arguments  and inherited environment variables bypasing the system shell.
            * If succeded, information about the spawned process is written to the \p child structure.
            *
            * \param  cmd   name of the application to be executed
            * \param  argv  vector of arguments (excluding argument zero)
            * \param  type  open pipe for read from child or write to child
            * \param  child on success is populated with child process information, on failure is not defined
            * \return true  on success, false on failure
            */
            static bool executeBackgroundEnv(const std::string& cmd, const std::vector<std::string>& argv, PipeType type, ChildHandle& child);

            //! Close the pipe and wait for a child to finish execution
            /*!
            * \param  child  structure with child process information as populated by executeBackground
            * \return result code as for std::system and UNIX pclose
            */
            static int closeBackground(ChildHandle& child);

        private:

            //! Spawn a process and open pipe with the specified type (READ or WRITE)
            static bool executeBackground(const std::string& cmd, char* const argv[], bool env, PipeType type, ChildHandle& child);

            //! Utility method. Cast argument to a C pointer required by some C-style functions.
            static inline char* castArgument(const std::string& arg);

            //! Utility method. Convert argument vector to a format required by execve and posix_spawn.
            static std::vector<char*> castArgVector(const std::string& cmd, const std::vector<std::string>& argv);

            //! Lightweight C++ wrapper with auto-close for file descriptors
            class FdWrapper {

                public:
                    static const int FD_NOT_READY = -1;

                    explicit FdWrapper(int fd = FD_NOT_READY);
                    ~FdWrapper();

                    inline int get() const;
                    int release();
                    void reset(int fd = FD_NOT_READY);

                private:
                    int m_fd;

            };

            //! Utility structure, used by popen wrapper
            struct Pipe {
                FdWrapper parent;
                FdWrapper child;
            };

            //! Initialize UNIX pipe
            static int initPipe(Pipe& pipe, PipeType type);

    };
}

#endif