/* * 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 . * */ /*! \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 #include #include #include 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& 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& 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& 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& 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 castArgVector(const std::string& cmd, const std::vector& 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