Annotation of truecrypt/platform/unix/process.cpp, revision 1.1.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.