Annotation of truecrypt/platform/unix/process.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
        !             3: 
        !             4:  Governed by the TrueCrypt License 2.4 the full text of which is contained
        !             5:  in the file License.txt included in TrueCrypt binary and source code
        !             6:  distribution packages.
        !             7: */
        !             8: 
        !             9: #include <fcntl.h>
        !            10: #include <unistd.h>
        !            11: #include <sys/stat.h>
        !            12: #include <sys/wait.h>
        !            13: #include "Process.h"
        !            14: #include "Platform/Exception.h"
        !            15: #include "Platform/FileStream.h"
        !            16: #include "Platform/ForEach.h"
        !            17: #include "Platform/MemoryStream.h"
        !            18: #include "Platform/SystemException.h"
        !            19: #include "Platform/StringConverter.h"
        !            20: #include "Platform/Unix/Pipe.h"
        !            21: #include "Platform/Unix/Poller.h"
        !            22: 
        !            23: namespace TrueCrypt
        !            24: {
        !            25:        string Process::Execute (const string &processName, const list <string> &arguments, int timeOut, ProcessExecFunctor *execFunctor)
        !            26:        {
        !            27:                char *args[32];
        !            28:                if (array_capacity (args) <= arguments.size())
        !            29:                        throw ParameterTooLarge (SRC_POS);
        !            30: 
        !            31: #if 0
        !            32:                stringstream dbg;
        !            33:                dbg << "exec " << processName;
        !            34:                foreach (const string &at, arguments)
        !            35:                        dbg << " " << at;
        !            36:                trace_msg (dbg.str());
        !            37: #endif
        !            38: 
        !            39:                Pipe outPipe, errPipe, exceptionPipe;
        !            40: 
        !            41:                int forkedPid = fork();
        !            42:                throw_sys_if (forkedPid == -1);
        !            43: 
        !            44:                if (forkedPid == 0)
        !            45:                {
        !            46:                        try
        !            47:                        {
        !            48:                                try
        !            49:                                {
        !            50:                                        int argIndex = 0;
        !            51:                                        if (!execFunctor)
        !            52:                                                args[argIndex++] = const_cast <char*> (processName.c_str());
        !            53: 
        !            54:                                        foreach (const string &arg, arguments)
        !            55:                                        {
        !            56:                                                args[argIndex++] = const_cast <char*> (arg.c_str());
        !            57:                                        }
        !            58:                                        args[argIndex] = nullptr;
        !            59: 
        !            60:                                        int f = open ("/dev/null", 0);
        !            61:                                        throw_sys_sub_if (f == -1, "/dev/null");
        !            62:                                        throw_sys_if (dup2 (f, STDIN_FILENO) == -1);
        !            63:                                        throw_sys_if (dup2 (outPipe.GetWriteFD(), STDOUT_FILENO) == -1);
        !            64:                                        throw_sys_if (dup2 (errPipe.GetWriteFD(), STDERR_FILENO) == -1);
        !            65:                                        exceptionPipe.GetWriteFD();
        !            66: 
        !            67:                                        if (execFunctor)
        !            68:                                        {
        !            69:                                                (*execFunctor)(argIndex, args);
        !            70:                                        }
        !            71:                                        else
        !            72:                                        {
        !            73:                                                execvp (args[0], args);
        !            74:                                                throw SystemException (SRC_POS, args[0]);
        !            75:                                        }
        !            76:                                }
        !            77:                                catch (Exception &)
        !            78:                                {
        !            79:                                        throw;
        !            80:                                }
        !            81:                                catch (exception &e)
        !            82:                                {
        !            83:                                        throw ExternalException (SRC_POS, StringConverter::ToExceptionString (e));
        !            84:                                }
        !            85:                                catch (...)
        !            86:                                {
        !            87:                                        throw UnknownException (SRC_POS);
        !            88:                                }
        !            89:                        }
        !            90:                        catch (Exception &e)
        !            91:                        {
        !            92:                                try
        !            93:                                {
        !            94:                                        shared_ptr <Stream> outputStream (new FileStream (exceptionPipe.GetWriteFD()));
        !            95:                                        e.Serialize (outputStream);
        !            96:                                }
        !            97:                                catch (...) { }
        !            98:                        }
        !            99: 
        !           100:                        _exit (1);
        !           101:                }
        !           102: 
        !           103:                throw_sys_if (fcntl (outPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1);
        !           104:                throw_sys_if (fcntl (errPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1);
        !           105:                throw_sys_if (fcntl (exceptionPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1);
        !           106: 
        !           107:                vector <char> buffer (4096), stdOutput (4096), errOutput (4096), exOutput (4096);
        !           108:                buffer.clear ();
        !           109:                stdOutput.clear ();
        !           110:                errOutput.clear ();
        !           111:                exOutput.clear ();
        !           112: 
        !           113:                Poller poller (outPipe.GetReadFD(), errPipe.GetReadFD(), exceptionPipe.GetReadFD());
        !           114:                int status, waitRes;
        !           115: 
        !           116:                int timeTaken = 0;
        !           117:                do
        !           118:                {
        !           119:                        const int pollTimeout = 200;
        !           120:                        try
        !           121:                        {
        !           122:                                ssize_t bytesRead = 0;
        !           123:                                foreach (int fd, poller.WaitForData (pollTimeout))
        !           124:                                {
        !           125:                                        bytesRead = read (fd, &buffer[0], buffer.capacity());
        !           126:                                        if (bytesRead > 0)
        !           127:                                        {
        !           128:                                                if (fd == outPipe.GetReadFD())
        !           129:                                                        stdOutput.insert (stdOutput.end(), buffer.begin(), buffer.begin() + bytesRead);
        !           130:                                                else if (fd == errPipe.GetReadFD())
        !           131:                                                        errOutput.insert (errOutput.end(), buffer.begin(), buffer.begin() + bytesRead);
        !           132:                                                else if (fd == exceptionPipe.GetReadFD())
        !           133:                                                        exOutput.insert (exOutput.end(), buffer.begin(), buffer.begin() + bytesRead);
        !           134:                                        }
        !           135:                                }
        !           136: 
        !           137:                                if (bytesRead == 0)
        !           138:                                {
        !           139:                                        waitRes = waitpid (forkedPid, &status, 0);
        !           140:                                        break;
        !           141:                                }
        !           142:                        }
        !           143:                        catch (TimeOut&)
        !           144:                        {
        !           145:                                timeTaken += pollTimeout;
        !           146:                                if (timeOut >= 0 && timeTaken >= timeOut)
        !           147:                                        throw;
        !           148:                        }
        !           149:                } while ((waitRes = waitpid (forkedPid, &status, WNOHANG)) == 0);
        !           150:                throw_sys_if (waitRes == -1);
        !           151: 
        !           152:                stdOutput.push_back (0);
        !           153:                errOutput.push_back (0);
        !           154: 
        !           155:                if (!exOutput.empty())
        !           156:                {
        !           157:                        auto_ptr <Serializable> deserializedObject;
        !           158:                        Exception *deserializedException = nullptr;
        !           159: 
        !           160:                        try
        !           161:                        {
        !           162:                                shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((byte *) &exOutput[0], exOutput.size())));
        !           163:                                deserializedObject.reset (Serializable::DeserializeNew (stream));
        !           164:                                deserializedException = dynamic_cast <Exception*> (deserializedObject.get());
        !           165:                        }
        !           166:                        catch (...)     { }
        !           167: 
        !           168:                        if (deserializedException)
        !           169:                                deserializedException->Throw();
        !           170:                }
        !           171: 
        !           172:                int exitCode = (WIFEXITED (status) ? WEXITSTATUS (status) : 1);
        !           173:                if (exitCode != 0)
        !           174:                {
        !           175:                        string strErrOutput;
        !           176:                        strErrOutput.insert (strErrOutput.begin(), errOutput.begin(), errOutput.end());
        !           177:                        throw ExecutedProcessFailed (SRC_POS, processName, exitCode, strErrOutput);
        !           178:                }
        !           179: 
        !           180:                string strOutput;
        !           181:                strOutput.insert (strOutput.begin(), stdOutput.begin(), stdOutput.end());
        !           182:                return strOutput;
        !           183:        }
        !           184: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.