|
|
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: #define _LARGEFILE_SOURCE 1 ! 10: #define _FILE_OFFSET_BITS 64 ! 11: ! 12: #include <errno.h> ! 13: #ifdef TC_LINUX ! 14: #include <sys/mount.h> ! 15: #endif ! 16: #ifdef TC_BSD ! 17: #include <sys/disk.h> ! 18: #endif ! 19: #include <sys/file.h> ! 20: #include <sys/types.h> ! 21: #include <sys/stat.h> ! 22: #include <fcntl.h> ! 23: #include <unistd.h> ! 24: #include <utime.h> ! 25: #include "Platform/File.h" ! 26: ! 27: namespace TrueCrypt ! 28: { ! 29: void File::Close () ! 30: { ! 31: ValidateState(); ! 32: ! 33: if (!SharedHandle) ! 34: { ! 35: close (FileHandle); ! 36: FileIsOpen = false; ! 37: ! 38: if ((mFileOpenFlags & File::PreserveTimestamps) && Path.IsFile()) ! 39: { ! 40: struct utimbuf u; ! 41: u.actime = AccTime; ! 42: u.modtime = ModTime; ! 43: throw_sys_sub_if (utime (string (Path).c_str(), &u) == -1, wstring (Path)); ! 44: } ! 45: } ! 46: } ! 47: ! 48: void File::Delete () ! 49: { ! 50: Close(); ! 51: Path.Delete(); ! 52: } ! 53: ! 54: ! 55: void File::Flush () const ! 56: { ! 57: ValidateState(); ! 58: throw_sys_sub_if (fsync (FileHandle) != 0, wstring (Path)); ! 59: } ! 60: ! 61: uint32 File::GetDeviceSectorSize () const ! 62: { ! 63: if (Path.IsDevice()) ! 64: { ! 65: #ifdef TC_LINUX ! 66: int blockSize; ! 67: throw_sys_sub_if (ioctl (FileHandle, BLKSSZGET, &blockSize) == -1, wstring (Path)); ! 68: return blockSize; ! 69: ! 70: #elif defined (TC_MACOSX) ! 71: uint32 blockSize; ! 72: throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path)); ! 73: return blockSize; ! 74: #endif ! 75: } ! 76: ! 77: return 512; ! 78: } ! 79: ! 80: uint64 File::Length () const ! 81: { ! 82: ValidateState(); ! 83: ! 84: // BSD does not support seeking to the end of a device ! 85: #ifdef TC_BSD ! 86: if (Path.IsBlockDevice() || Path.IsCharacterDevice()) ! 87: { ! 88: # ifdef TC_MACOSX ! 89: uint32 blockSize; ! 90: uint64 blockCount; ! 91: throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path)); ! 92: throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKCOUNT, &blockCount) == -1, wstring (Path)); ! 93: return blockCount * blockSize; ! 94: # else ! 95: uint64 mediaSize; ! 96: throw_sys_sub_if (ioctl (FileHandle, DIOCGMEDIASIZE, &mediaSize) == -1, wstring (Path)); ! 97: return mediaSize; ! 98: # endif ! 99: } ! 100: #endif ! 101: off_t current = lseek (FileHandle, 0, SEEK_CUR); ! 102: throw_sys_sub_if (current == -1, wstring (Path)); ! 103: SeekEnd (0); ! 104: uint64 length = lseek (FileHandle, 0, SEEK_CUR); ! 105: SeekAt (current); ! 106: return length; ! 107: } ! 108: ! 109: void File::Open (const FilePath &path, FileOpenMode mode, FileShareMode shareMode, FileOpenFlags flags) ! 110: { ! 111: #ifdef TC_LINUX ! 112: int sysFlags = O_LARGEFILE; ! 113: #else ! 114: int sysFlags = 0; ! 115: #endif ! 116: ! 117: switch (mode) ! 118: { ! 119: case CreateReadWrite: ! 120: sysFlags |= O_CREAT | O_TRUNC | O_RDWR; ! 121: break; ! 122: ! 123: case CreateWrite: ! 124: sysFlags |= O_CREAT | O_TRUNC | O_WRONLY; ! 125: break; ! 126: ! 127: case OpenRead: ! 128: sysFlags |= O_RDONLY; ! 129: break; ! 130: ! 131: case OpenWrite: ! 132: sysFlags |= O_WRONLY; ! 133: break; ! 134: ! 135: case OpenReadWrite: ! 136: sysFlags |= O_RDWR; ! 137: break; ! 138: ! 139: default: ! 140: throw ParameterIncorrect (SRC_POS); ! 141: } ! 142: ! 143: if ((flags & File::PreserveTimestamps) && path.IsFile()) ! 144: { ! 145: struct stat statData; ! 146: throw_sys_sub_if (stat (string (path).c_str(), &statData) == -1, wstring (path)); ! 147: AccTime = statData.st_atime; ! 148: ModTime = statData.st_mtime; ! 149: } ! 150: ! 151: FileHandle = open (string (path).c_str(), sysFlags, S_IRUSR | S_IWUSR); ! 152: throw_sys_sub_if (FileHandle == -1, wstring (path)); ! 153: ! 154: try ! 155: { ! 156: switch (shareMode) ! 157: { ! 158: case ShareNone: ! 159: if (flock (FileHandle, LOCK_EX | LOCK_NB) == -1) ! 160: throw_sys_sub_if (errno == EAGAIN, wstring (path)); ! 161: break; ! 162: ! 163: case ShareRead: ! 164: if (flock (FileHandle, LOCK_SH | LOCK_NB) == -1) ! 165: throw_sys_sub_if (errno == EAGAIN, wstring (path)); ! 166: break; ! 167: ! 168: case ShareReadWrite: ! 169: if (flock (FileHandle, (mode == OpenRead ? LOCK_SH : LOCK_EX) | LOCK_NB) == -1) ! 170: throw_sys_sub_if (errno == EAGAIN, wstring (path)); ! 171: flock (FileHandle, LOCK_UN | LOCK_NB); ! 172: break; ! 173: ! 174: case ShareReadWriteIgnoreLock: ! 175: break; ! 176: ! 177: default: ! 178: throw ParameterIncorrect (SRC_POS); ! 179: } ! 180: } ! 181: catch (...) ! 182: { ! 183: close (FileHandle); ! 184: throw; ! 185: } ! 186: ! 187: Path = path; ! 188: mFileOpenFlags = flags; ! 189: FileIsOpen = true; ! 190: } ! 191: ! 192: uint64 File::Read (const BufferPtr &buffer) const ! 193: { ! 194: ValidateState(); ! 195: ! 196: ssize_t bytesRead = read (FileHandle, buffer, buffer.Size()); ! 197: throw_sys_sub_if (bytesRead == -1, wstring (Path)); ! 198: ! 199: return bytesRead; ! 200: } ! 201: ! 202: uint64 File::ReadAt (const BufferPtr &buffer, uint64 position) const ! 203: { ! 204: ValidateState(); ! 205: ! 206: ssize_t bytesRead = pread (FileHandle, buffer, buffer.Size(), position); ! 207: throw_sys_sub_if (bytesRead == -1, wstring (Path)); ! 208: ! 209: return bytesRead; ! 210: } ! 211: ! 212: void File::SeekAt (uint64 position) const ! 213: { ! 214: ValidateState(); ! 215: throw_sys_sub_if (lseek (FileHandle, position, SEEK_SET) == -1, wstring (Path)); ! 216: } ! 217: ! 218: void File::SeekEnd (int offset) const ! 219: { ! 220: ValidateState(); ! 221: ! 222: // BSD does not support seeking to the end of a device ! 223: #ifdef TC_BSD ! 224: if (Path.IsBlockDevice() || Path.IsCharacterDevice()) ! 225: { ! 226: SeekAt (Length() + offset); ! 227: return; ! 228: } ! 229: #endif ! 230: ! 231: throw_sys_sub_if (lseek (FileHandle, offset, SEEK_END) == -1, wstring (Path)); ! 232: } ! 233: ! 234: void File::Write (const ConstBufferPtr &buffer) const ! 235: { ! 236: ValidateState(); ! 237: throw_sys_sub_if (write (FileHandle, buffer, buffer.Size()) != buffer.Size(), wstring (Path)); ! 238: } ! 239: ! 240: void File::WriteAt (const ConstBufferPtr &buffer, uint64 position) const ! 241: { ! 242: ValidateState(); ! 243: throw_sys_sub_if (pwrite (FileHandle, buffer, buffer.Size(), position) != buffer.Size(), wstring (Path)); ! 244: } ! 245: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.