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