1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-12 03:18:26 -06:00

Add TrueCrypt 7.1a MacOSX/Linux specific source files.

This commit is contained in:
Mounir IDRASSI
2014-05-31 18:44:53 +02:00
parent 97011f179c
commit 7ffce028d0
203 changed files with 52120 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
/*
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include "System.h"
#include "Platform/Directory.h"
#include "Platform/Finally.h"
#include "Platform/SystemException.h"
namespace TrueCrypt
{
static Mutex ReadDirMutex; // readdir_r() may be unsafe on some systems
void Directory::Create (const DirectoryPath &path)
{
string p = path;
throw_sys_sub_if (mkdir (p.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) == -1, p);
}
DirectoryPath Directory::AppendSeparator (const DirectoryPath &path)
{
wstring p (path);
if (p.find_last_of (L'/') + 1 != p.size())
return p + L'/';
return p;
}
FilePathList Directory::GetFilePaths (const DirectoryPath &path, bool regularFilesOnly)
{
DIR *dir = opendir (string (path).c_str());
throw_sys_sub_if (!dir, wstring (path));
finally_do_arg (DIR*, dir, { closedir (finally_arg); });
ScopeLock lock (ReadDirMutex);
FilePathList files;
struct dirent *dirEntry;
errno = 0;
while ((dirEntry = readdir (dir)) != nullptr)
{
shared_ptr <FilePath> filePath (new FilePath (string (AppendSeparator (path)) + string (dirEntry->d_name)));
if (!regularFilesOnly || filePath->IsFile())
files.push_back (filePath);
errno = 0;
}
throw_sys_sub_if (errno != 0, wstring (path));
return files;
}
}

348
src/Platform/Unix/File.cpp Normal file
View File

@@ -0,0 +1,348 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <utime.h>
#ifdef TC_LINUX
#include <sys/mount.h>
#endif
#ifdef TC_BSD
#include <sys/disk.h>
#endif
#ifdef TC_SOLARIS
#include <stropts.h>
#include <sys/dkio.h>
#endif
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "Platform/File.h"
#include "Platform/TextReader.h"
namespace TrueCrypt
{
#if 0
# define TC_TRACE_FILE_OPERATIONS
static void TraceFileOperation (int fileHandle, FilePath filePath, bool write, uint64 length, int64 position = -1)
{
string path = filePath;
if (path.empty() || path.find ("truecrypt_aux_mnt") != string::npos)
return;
stringstream s;
s << path << ": " << (write ? "W " : "R ") << (position == -1 ? lseek (fileHandle, 0, SEEK_CUR) : position) << " (" << length << ")";
SystemLog::WriteError (s.str());
}
#endif
void File::Close ()
{
if_debug (ValidateState());
if (!SharedHandle)
{
close (FileHandle);
FileIsOpen = false;
if ((mFileOpenFlags & File::PreserveTimestamps) && Path.IsFile())
{
struct utimbuf u;
u.actime = AccTime;
u.modtime = ModTime;
try
{
throw_sys_sub_if (utime (string (Path).c_str(), &u) == -1, wstring (Path));
}
catch (...) // Suppress errors to allow using read-only files
{
#ifdef DEBUG
throw;
#endif
}
}
}
}
void File::Delete ()
{
Close();
Path.Delete();
}
void File::Flush () const
{
if_debug (ValidateState());
throw_sys_sub_if (fsync (FileHandle) != 0, wstring (Path));
}
uint32 File::GetDeviceSectorSize () const
{
if (Path.IsDevice())
{
#ifdef TC_LINUX
int blockSize;
throw_sys_sub_if (ioctl (FileHandle, BLKSSZGET, &blockSize) == -1, wstring (Path));
return blockSize;
#elif defined (TC_MACOSX)
uint32 blockSize;
throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path));
return blockSize;
#elif defined (TC_FREEBSD)
u_int sectorSize;
throw_sys_sub_if (ioctl (FileHandle, DIOCGSECTORSIZE, &sectorSize) == -1, wstring (Path));
return (uint32) sectorSize;
#elif defined (TC_SOLARIS)
struct dk_minfo mediaInfo;
throw_sys_sub_if (ioctl (FileHandle, DKIOCGMEDIAINFO, &mediaInfo) == -1, wstring (Path));
return mediaInfo.dki_lbsize;
#else
# error GetDeviceSectorSize()
#endif
}
else
throw ParameterIncorrect (SRC_POS);
}
uint64 File::GetPartitionDeviceStartOffset () const
{
#ifdef TC_LINUX
// HDIO_GETGEO ioctl is limited by the size of long
TextReader tr ("/sys/block/" + string (Path.ToHostDriveOfPartition().ToBaseName()) + "/" + string (Path.ToBaseName()) + "/start");
string line;
tr.ReadLine (line);
return StringConverter::ToUInt64 (line) * GetDeviceSectorSize();
#elif defined (TC_MACOSX)
#ifndef DKIOCGETBASE
# define DKIOCGETBASE _IOR('d', 73, uint64)
#endif
uint64 offset;
throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBASE, &offset) == -1, wstring (Path));
return offset;
#elif defined (TC_SOLARIS)
struct extpart_info partInfo;
throw_sys_sub_if (ioctl (FileHandle, DKIOCEXTPARTINFO, &partInfo) == -1, wstring (Path));
return partInfo.p_start * GetDeviceSectorSize();
#else
throw NotImplemented (SRC_POS);
#endif
}
uint64 File::Length () const
{
if_debug (ValidateState());
// BSD does not support seeking to the end of a device
#ifdef TC_BSD
if (Path.IsBlockDevice() || Path.IsCharacterDevice())
{
# ifdef TC_MACOSX
uint32 blockSize;
uint64 blockCount;
throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path));
throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKCOUNT, &blockCount) == -1, wstring (Path));
return blockCount * blockSize;
# else
uint64 mediaSize;
throw_sys_sub_if (ioctl (FileHandle, DIOCGMEDIASIZE, &mediaSize) == -1, wstring (Path));
return mediaSize;
# endif
}
#endif
off_t current = lseek (FileHandle, 0, SEEK_CUR);
throw_sys_sub_if (current == -1, wstring (Path));
SeekEnd (0);
uint64 length = lseek (FileHandle, 0, SEEK_CUR);
SeekAt (current);
return length;
}
void File::Open (const FilePath &path, FileOpenMode mode, FileShareMode shareMode, FileOpenFlags flags)
{
#ifdef TC_LINUX
int sysFlags = O_LARGEFILE;
#else
int sysFlags = 0;
#endif
switch (mode)
{
case CreateReadWrite:
sysFlags |= O_CREAT | O_TRUNC | O_RDWR;
break;
case CreateWrite:
sysFlags |= O_CREAT | O_TRUNC | O_WRONLY;
break;
case OpenRead:
sysFlags |= O_RDONLY;
break;
case OpenWrite:
sysFlags |= O_WRONLY;
break;
case OpenReadWrite:
sysFlags |= O_RDWR;
break;
default:
throw ParameterIncorrect (SRC_POS);
}
if ((flags & File::PreserveTimestamps) && path.IsFile())
{
struct stat statData;
throw_sys_sub_if (stat (string (path).c_str(), &statData) == -1, wstring (path));
AccTime = statData.st_atime;
ModTime = statData.st_mtime;
}
FileHandle = open (string (path).c_str(), sysFlags, S_IRUSR | S_IWUSR);
throw_sys_sub_if (FileHandle == -1, wstring (path));
#if 0 // File locking is disabled to avoid remote filesystem locking issues
try
{
struct flock fl;
memset (&fl, 0, sizeof (fl));
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
switch (shareMode)
{
case ShareNone:
fl.l_type = F_WRLCK;
if (fcntl (FileHandle, F_SETLK, &fl) == -1)
throw_sys_sub_if (errno == EAGAIN || errno == EACCES, wstring (path));
break;
case ShareRead:
fl.l_type = F_RDLCK;
if (fcntl (FileHandle, F_SETLK, &fl) == -1)
throw_sys_sub_if (errno == EAGAIN || errno == EACCES, wstring (path));
break;
case ShareReadWrite:
fl.l_type = (mode == OpenRead ? F_RDLCK : F_WRLCK);
if (fcntl (FileHandle, F_GETLK, &fl) != -1 && fl.l_type != F_UNLCK)
{
errno = EAGAIN;
throw SystemException (SRC_POS, wstring (path));
}
break;
case ShareReadWriteIgnoreLock:
break;
default:
throw ParameterIncorrect (SRC_POS);
}
}
catch (...)
{
close (FileHandle);
throw;
}
#endif // 0
Path = path;
mFileOpenFlags = flags;
FileIsOpen = true;
}
uint64 File::Read (const BufferPtr &buffer) const
{
if_debug (ValidateState());
#ifdef TC_TRACE_FILE_OPERATIONS
TraceFileOperation (FileHandle, Path, false, buffer.Size());
#endif
ssize_t bytesRead = read (FileHandle, buffer, buffer.Size());
throw_sys_sub_if (bytesRead == -1, wstring (Path));
return bytesRead;
}
uint64 File::ReadAt (const BufferPtr &buffer, uint64 position) const
{
if_debug (ValidateState());
#ifdef TC_TRACE_FILE_OPERATIONS
TraceFileOperation (FileHandle, Path, false, buffer.Size(), position);
#endif
ssize_t bytesRead = pread (FileHandle, buffer, buffer.Size(), position);
throw_sys_sub_if (bytesRead == -1, wstring (Path));
return bytesRead;
}
void File::SeekAt (uint64 position) const
{
if_debug (ValidateState());
throw_sys_sub_if (lseek (FileHandle, position, SEEK_SET) == -1, wstring (Path));
}
void File::SeekEnd (int offset) const
{
if_debug (ValidateState());
// BSD does not support seeking to the end of a device
#ifdef TC_BSD
if (Path.IsBlockDevice() || Path.IsCharacterDevice())
{
SeekAt (Length() + offset);
return;
}
#endif
throw_sys_sub_if (lseek (FileHandle, offset, SEEK_END) == -1, wstring (Path));
}
void File::Write (const ConstBufferPtr &buffer) const
{
if_debug (ValidateState());
#ifdef TC_TRACE_FILE_OPERATIONS
TraceFileOperation (FileHandle, Path, true, buffer.Size());
#endif
throw_sys_sub_if (write (FileHandle, buffer, buffer.Size()) != (ssize_t) buffer.Size(), wstring (Path));
}
void File::WriteAt (const ConstBufferPtr &buffer, uint64 position) const
{
if_debug (ValidateState());
#ifdef TC_TRACE_FILE_OPERATIONS
TraceFileOperation (FileHandle, Path, true, buffer.Size(), position);
#endif
throw_sys_sub_if (pwrite (FileHandle, buffer, buffer.Size(), position) != (ssize_t) buffer.Size(), wstring (Path));
}
}

View File

@@ -0,0 +1,96 @@
/*
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include "Platform/FilesystemPath.h"
#include "Platform/SystemException.h"
#include "Platform/StringConverter.h"
#include <stdio.h>
#include <sys/stat.h>
namespace TrueCrypt
{
void FilesystemPath::Delete () const
{
throw_sys_sub_if (remove (string (*this).c_str()) == -1, Path);
}
UserId FilesystemPath::GetOwner () const
{
struct stat statData;
throw_sys_if (stat (StringConverter::ToSingle (Path).c_str(), &statData) == -1);
UserId owner;
owner.SystemId = statData.st_uid;
return owner;
}
FilesystemPathType::Enum FilesystemPath::GetType () const
{
// Strip trailing directory separator
wstring path = Path;
size_t pos = path.find_last_not_of (L'/');
if (path.size() > 2 && pos != path.size() - 1)
path = path.substr (0, pos + 1);
struct stat statData;
throw_sys_sub_if (stat (StringConverter::ToSingle (path).c_str(), &statData) != 0, Path);
if (S_ISREG (statData.st_mode)) return FilesystemPathType::File;
if (S_ISDIR (statData.st_mode)) return FilesystemPathType::Directory;
if (S_ISCHR (statData.st_mode)) return FilesystemPathType::CharacterDevice;
if (S_ISBLK (statData.st_mode)) return FilesystemPathType::BlockDevice;
if (S_ISLNK (statData.st_mode)) return FilesystemPathType::SymbolickLink;
return FilesystemPathType::Unknown;
}
FilesystemPath FilesystemPath::ToBaseName () const
{
wstring path = Path;
size_t pos = path.find_last_of (L'/');
if (pos == string::npos)
return Path;
return Path.substr (pos + 1);
}
FilesystemPath FilesystemPath::ToHostDriveOfPartition () const
{
DevicePath path;
#ifdef TC_LINUX
path = StringConverter::StripTrailingNumber (StringConverter::ToSingle (Path));
#elif defined (TC_MACOSX)
string pathStr = StringConverter::StripTrailingNumber (StringConverter::ToSingle (Path));
path = pathStr.substr (0, pathStr.size() - 1);
#elif defined (TC_FREEBSD)
string pathStr = StringConverter::ToSingle (Path);
size_t p = pathStr.rfind ("s");
if (p == string::npos)
throw PartitionDeviceRequired (SRC_POS);
path = pathStr.substr (0, p);
#elif defined (TC_SOLARIS)
path = StringConverter::StripTrailingNumber (StringConverter::ToSingle (Path)) + "0";
#else
throw NotImplemented (SRC_POS);
#endif
if (!path.IsDevice())
throw PartitionDeviceRequired (SRC_POS);
return path;
}
}

View File

@@ -0,0 +1,62 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <pthread.h>
#include "Platform/Mutex.h"
#include "Platform/SystemException.h"
namespace TrueCrypt
{
Mutex::Mutex ()
{
pthread_mutexattr_t attributes;
int status = pthread_mutexattr_init (&attributes);
if (status != 0)
throw SystemException (SRC_POS, status);
status = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);
if (status != 0)
throw SystemException (SRC_POS, status);
status = pthread_mutex_init (&SystemMutex, &attributes);
if (status != 0)
throw SystemException (SRC_POS, status);
Initialized = true;
}
Mutex::~Mutex ()
{
Initialized = false;
#ifdef DEBUG
int status =
#endif
pthread_mutex_destroy (&SystemMutex);
#ifdef DEBUG
if (status != 0)
SystemLog::WriteException (SystemException (SRC_POS, status));
#endif
}
void Mutex::Lock ()
{
assert (Initialized);
int status = pthread_mutex_lock (&SystemMutex);
if (status != 0)
throw SystemException (SRC_POS, status);
}
void Mutex::Unlock ()
{
int status = pthread_mutex_unlock (&SystemMutex);
if (status != 0)
throw SystemException (SRC_POS, status);
}
}

View File

@@ -0,0 +1,65 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <unistd.h>
#include "Pipe.h"
#include "Platform/SystemException.h"
namespace TrueCrypt
{
Pipe::Pipe ()
{
int fd[2];
throw_sys_if (pipe (fd) == -1);
ReadFileDescriptor = fd[0];
WriteFileDescriptor = fd[1];
}
Pipe::~Pipe ()
{
try
{
Close();
}
catch (...) { }
}
void Pipe::Close ()
{
if (ReadFileDescriptor != -1)
close (ReadFileDescriptor);
if (WriteFileDescriptor != -1)
close (WriteFileDescriptor);
}
int Pipe::GetReadFD ()
{
assert (ReadFileDescriptor != -1);
if (WriteFileDescriptor != -1)
{
close (WriteFileDescriptor);
WriteFileDescriptor = -1;
}
return ReadFileDescriptor;
}
int Pipe::GetWriteFD ()
{
assert (WriteFileDescriptor != -1);
if (ReadFileDescriptor != -1)
{
close (ReadFileDescriptor);
ReadFileDescriptor = -1;
}
return WriteFileDescriptor;
}
}

38
src/Platform/Unix/Pipe.h Normal file
View File

@@ -0,0 +1,38 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Platform_Unix_Pipe
#define TC_HEADER_Platform_Unix_Pipe
#include "Platform/PlatformBase.h"
namespace TrueCrypt
{
class Pipe
{
public:
Pipe ();
virtual ~Pipe ();
void Close ();
int GetReadFD ();
int GetWriteFD ();
int PeekReadFD () const { return ReadFileDescriptor; }
int PeekWriteFD () const { return WriteFileDescriptor; }
protected:
int ReadFileDescriptor;
int WriteFileDescriptor;
private:
Pipe (const Pipe &);
Pipe &operator= (const Pipe &);
};
}
#endif // TC_HEADER_Platform_Unix_Pipe

View File

@@ -0,0 +1,57 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <poll.h>
#include <unistd.h>
#include "Poller.h"
#include "Platform/SystemException.h"
namespace TrueCrypt
{
Poller::Poller (int fileDescriptor1, int fileDescriptor2, int fileDescriptor3, int fileDescriptor4)
{
FileDescriptors.push_back (fileDescriptor1);
if (fileDescriptor2 != -1)
FileDescriptors.push_back (fileDescriptor2);
if (fileDescriptor3 != -1)
FileDescriptors.push_back (fileDescriptor3);
if (fileDescriptor4 != -1)
FileDescriptors.push_back (fileDescriptor4);
}
list <int> Poller::WaitForData (int timeOut) const
{
vector <pollfd> pfd (FileDescriptors.size());
for (size_t i = 0; i < FileDescriptors.size(); i++)
{
pfd[i].fd = FileDescriptors[i];
pfd[i].events = POLLIN;
}
list <int> descList;
int pollRes = poll (&pfd[0], pfd.size(), timeOut);
if (pollRes == 0 && timeOut != -1)
throw TimeOut (SRC_POS);
if (pollRes > 0)
{
for (size_t i = 0; i < pfd.size(); i++)
{
if (pfd[i].revents & POLLIN)
descList.push_back (pfd[i].fd);
}
}
return descList;
}
}

View File

@@ -0,0 +1,33 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Platform_Unix_Poller
#define TC_HEADER_Platform_Unix_Poller
#include "Platform/PlatformBase.h"
namespace TrueCrypt
{
class Poller
{
public:
Poller (int fileDescriptor1, int fileDescriptor2 = -1, int fileDescriptor3 = -1, int fileDescriptor4 = -1);
virtual ~Poller () { }
list <int> WaitForData (int timeOut = -1) const;
protected:
vector <int> FileDescriptors;
private:
Poller (const Poller &);
Poller &operator= (const Poller &);
};
}
#endif // TC_HEADER_Platform_Unix_Poller

View File

@@ -0,0 +1,202 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include "Process.h"
#include "Platform/Exception.h"
#include "Platform/FileStream.h"
#include "Platform/ForEach.h"
#include "Platform/MemoryStream.h"
#include "Platform/SystemException.h"
#include "Platform/StringConverter.h"
#include "Platform/Unix/Pipe.h"
#include "Platform/Unix/Poller.h"
namespace TrueCrypt
{
string Process::Execute (const string &processName, const list <string> &arguments, int timeOut, ProcessExecFunctor *execFunctor, const Buffer *inputData)
{
char *args[32];
if (array_capacity (args) <= arguments.size())
throw ParameterTooLarge (SRC_POS);
#if 0
stringstream dbg;
dbg << "exec " << processName;
foreach (const string &at, arguments)
dbg << " " << at;
trace_msg (dbg.str());
#endif
Pipe inPipe, outPipe, errPipe, exceptionPipe;
int forkedPid = fork();
throw_sys_if (forkedPid == -1);
if (forkedPid == 0)
{
try
{
try
{
int argIndex = 0;
if (!execFunctor)
args[argIndex++] = const_cast <char*> (processName.c_str());
foreach (const string &arg, arguments)
{
args[argIndex++] = const_cast <char*> (arg.c_str());
}
args[argIndex] = nullptr;
if (inputData)
{
throw_sys_if (dup2 (inPipe.GetReadFD(), STDIN_FILENO) == -1);
}
else
{
inPipe.Close();
int nullDev = open ("/dev/null", 0);
throw_sys_sub_if (nullDev == -1, "/dev/null");
throw_sys_if (dup2 (nullDev, STDIN_FILENO) == -1);
}
throw_sys_if (dup2 (outPipe.GetWriteFD(), STDOUT_FILENO) == -1);
throw_sys_if (dup2 (errPipe.GetWriteFD(), STDERR_FILENO) == -1);
exceptionPipe.GetWriteFD();
if (execFunctor)
{
(*execFunctor)(argIndex, args);
}
else
{
execvp (args[0], args);
throw SystemException (SRC_POS, args[0]);
}
}
catch (Exception &)
{
throw;
}
catch (exception &e)
{
throw ExternalException (SRC_POS, StringConverter::ToExceptionString (e));
}
catch (...)
{
throw UnknownException (SRC_POS);
}
}
catch (Exception &e)
{
try
{
shared_ptr <Stream> outputStream (new FileStream (exceptionPipe.GetWriteFD()));
e.Serialize (outputStream);
}
catch (...) { }
}
_exit (1);
}
throw_sys_if (fcntl (outPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1);
throw_sys_if (fcntl (errPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1);
throw_sys_if (fcntl (exceptionPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1);
vector <char> buffer (4096), stdOutput (4096), errOutput (4096), exOutput (4096);
buffer.clear ();
stdOutput.clear ();
errOutput.clear ();
exOutput.clear ();
Poller poller (outPipe.GetReadFD(), errPipe.GetReadFD(), exceptionPipe.GetReadFD());
int status, waitRes;
if (inputData)
throw_sys_if (write (inPipe.GetWriteFD(), inputData->Ptr(), inputData->Size()) == -1 && errno != EPIPE);
inPipe.Close();
int timeTaken = 0;
do
{
const int pollTimeout = 200;
try
{
ssize_t bytesRead = 0;
foreach (int fd, poller.WaitForData (pollTimeout))
{
bytesRead = read (fd, &buffer[0], buffer.capacity());
if (bytesRead > 0)
{
if (fd == outPipe.GetReadFD())
stdOutput.insert (stdOutput.end(), buffer.begin(), buffer.begin() + bytesRead);
else if (fd == errPipe.GetReadFD())
errOutput.insert (errOutput.end(), buffer.begin(), buffer.begin() + bytesRead);
else if (fd == exceptionPipe.GetReadFD())
exOutput.insert (exOutput.end(), buffer.begin(), buffer.begin() + bytesRead);
}
}
if (bytesRead == 0)
{
waitRes = waitpid (forkedPid, &status, 0);
break;
}
}
catch (TimeOut&)
{
timeTaken += pollTimeout;
if (timeOut >= 0 && timeTaken >= timeOut)
throw;
}
} while ((waitRes = waitpid (forkedPid, &status, WNOHANG)) == 0);
throw_sys_if (waitRes == -1);
if (!exOutput.empty())
{
auto_ptr <Serializable> deserializedObject;
Exception *deserializedException = nullptr;
try
{
shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((byte *) &exOutput[0], exOutput.size())));
deserializedObject.reset (Serializable::DeserializeNew (stream));
deserializedException = dynamic_cast <Exception*> (deserializedObject.get());
}
catch (...) { }
if (deserializedException)
deserializedException->Throw();
}
int exitCode = (WIFEXITED (status) ? WEXITSTATUS (status) : 1);
if (exitCode != 0)
{
string strErrOutput;
if (!errOutput.empty())
strErrOutput.insert (strErrOutput.begin(), errOutput.begin(), errOutput.end());
throw ExecutedProcessFailed (SRC_POS, processName, exitCode, strErrOutput);
}
string strOutput;
if (!stdOutput.empty())
strOutput.insert (strOutput.begin(), stdOutput.begin(), stdOutput.end());
return strOutput;
}
}

View File

@@ -0,0 +1,40 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Platform_Unix_Process
#define TC_HEADER_Platform_Unix_Process
#include "Platform/PlatformBase.h"
#include "Platform/Buffer.h"
#include "Platform/Functor.h"
namespace TrueCrypt
{
struct ProcessExecFunctor
{
virtual ~ProcessExecFunctor () { }
virtual void operator() (int argc, char *argv[]) = 0;
};
class Process
{
public:
Process ();
virtual ~Process ();
static string Execute (const string &processName, const list <string> &arguments, int timeOut = -1, ProcessExecFunctor *execFunctor = nullptr, const Buffer *inputData = nullptr);
protected:
private:
Process (const Process &);
Process &operator= (const Process &);
};
}
#endif // TC_HEADER_Platform_Unix_Process

View File

@@ -0,0 +1,68 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include "Platform/Exception.h"
#include "Platform/SyncEvent.h"
#include "Platform/SystemException.h"
namespace TrueCrypt
{
SyncEvent::SyncEvent ()
{
int status = pthread_cond_init (&SystemSyncEvent, nullptr);
if (status != 0)
throw SystemException (SRC_POS, status);
Signaled = false;
Initialized = true;
}
SyncEvent::~SyncEvent ()
{
#ifdef DEBUG
int status =
#endif
pthread_cond_destroy (&SystemSyncEvent);
#ifdef DEBUG
if (status != 0)
SystemLog::WriteException (SystemException (SRC_POS, status));
#endif
Initialized = false;
}
void SyncEvent::Signal ()
{
assert (Initialized);
ScopeLock lock (EventMutex);
Signaled = true;
int status = pthread_cond_signal (&SystemSyncEvent);
if (status != 0)
throw SystemException (SRC_POS, status);
}
void SyncEvent::Wait ()
{
assert (Initialized);
ScopeLock lock (EventMutex);
while (!Signaled)
{
int status = pthread_cond_wait (&SystemSyncEvent, EventMutex.GetSystemHandle());
if (status != 0)
throw SystemException (SRC_POS, status);
}
Signaled = false;
}
}

View File

@@ -0,0 +1,12 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Platform_Unix_System
#define TC_HEADER_Platform_Unix_System
#endif // TC_HEADER_Platform_Unix_System

View File

@@ -0,0 +1,66 @@
/*
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <errno.h>
#include <string.h>
#include "Platform/SerializerFactory.h"
#include "Platform/SystemException.h"
#include "Platform/StringConverter.h"
namespace TrueCrypt
{
SystemException::SystemException ()
: ErrorCode (errno)
{
}
SystemException::SystemException (const string &message)
: Exception (message), ErrorCode (errno)
{
}
SystemException::SystemException (const string &message, const string &subject)
: Exception (message, StringConverter::ToWide (subject)), ErrorCode (errno)
{
}
SystemException::SystemException (const string &message, const wstring &subject)
: Exception (message, subject), ErrorCode (errno)
{
}
void SystemException::Deserialize (shared_ptr <Stream> stream)
{
Exception::Deserialize (stream);
Serializer sr (stream);
sr.Deserialize ("ErrorCode", ErrorCode);
}
bool SystemException::IsError () const
{
return ErrorCode != 0;
}
void SystemException::Serialize (shared_ptr <Stream> stream) const
{
Exception::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("ErrorCode", ErrorCode);
}
wstring SystemException::SystemText () const
{
return StringConverter::ToWide (strerror ((int) ErrorCode));
}
#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
#undef TC_EXCEPTION_NODECL
#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (SystemException);
}

View File

@@ -0,0 +1,69 @@
/*
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include "Platform/SystemException.h"
#include "Platform/SystemInfo.h"
#include <sys/utsname.h>
namespace TrueCrypt
{
wstring SystemInfo::GetPlatformName ()
{
#ifdef TC_LINUX
return L"Linux";
#elif defined (TC_MACOSX)
return L"Mac OS X";
#elif defined (TC_FREEBSD)
return L"FreeBSD";
#elif defined (TC_SOLARIS)
return L"Solaris";
#else
# error GetPlatformName() undefined
#endif
}
vector <int> SystemInfo::GetVersion ()
{
struct utsname unameData;
throw_sys_if (uname (&unameData) == -1);
vector <string> versionStrings = StringConverter::Split (unameData.release, ".");
vector <int> version;
for (size_t i = 0; i < versionStrings.size(); ++i)
{
string s = versionStrings[i];
size_t p = s.find_first_not_of ("0123456789");
if (p != string::npos)
s = s.substr (0, p);
if (s.empty())
break;
version.push_back (StringConverter::ToUInt32 (s));
}
return version;
}
bool SystemInfo::IsVersionAtLeast (int versionNumber1, int versionNumber2, int versionNumber3)
{
vector <int> osVersionNumbers = GetVersion();
if (osVersionNumbers.size() < 2)
throw ParameterIncorrect (SRC_POS);
if (osVersionNumbers.size() < 3)
osVersionNumbers[2] = 0;
return (osVersionNumbers[0] * 10000000 + osVersionNumbers[1] * 10000 + osVersionNumbers[2]) >=
(versionNumber1 * 10000000 + versionNumber2 * 10000 + versionNumber3);
}
}

View File

@@ -0,0 +1,27 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <syslog.h>
#include "Platform/SystemLog.h"
namespace TrueCrypt
{
void SystemLog::WriteDebug (const string &debugMessage)
{
openlog ("truecrypt", LOG_PID, LOG_USER);
syslog (LOG_DEBUG, "%s", debugMessage.c_str());
closelog();
}
void SystemLog::WriteError (const string &errorMessage)
{
openlog ("truecrypt", LOG_PID, LOG_USER);
syslog (LOG_ERR, "%s", errorMessage.c_str());
closelog();
}
}

View File

@@ -0,0 +1,54 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <pthread.h>
#include <unistd.h>
#include "Platform/SystemException.h"
#include "Platform/Thread.h"
#include "Platform/SystemLog.h"
namespace TrueCrypt
{
void Thread::Join () const
{
int status = pthread_join (SystemHandle, nullptr);
if (status != 0)
throw SystemException (SRC_POS, status);
}
void Thread::Start (ThreadProcPtr threadProc, void *parameter)
{
pthread_attr_t attr;
size_t stackSize = 0;
int status;
status = pthread_attr_init (&attr);
if (status != 0)
throw SystemException (SRC_POS, status);
status = pthread_attr_getstacksize (&attr, &stackSize);
if (status != 0)
throw SystemException (SRC_POS, status);
if (stackSize < MinThreadStackSize)
{
status = pthread_attr_setstacksize (&attr, MinThreadStackSize);
if (status != 0)
throw SystemException (SRC_POS, status);
}
status = pthread_create (&SystemHandle, nullptr, threadProc, parameter);
if (status != 0)
throw SystemException (SRC_POS, status);
}
void Thread::Sleep (uint32 milliSeconds)
{
::usleep (milliSeconds * 1000);
}
}

View File

@@ -0,0 +1,23 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include "Platform/Time.h"
#include <sys/time.h>
#include <time.h>
namespace TrueCrypt
{
uint64 Time::GetCurrent ()
{
struct timeval tv;
gettimeofday (&tv, NULL);
// Unix time => Windows file time
return ((uint64) tv.tv_sec + 134774LL * 24 * 3600) * 1000LL * 1000 * 10;
}
}