blob: 72ea8fa378fe3528760f971a20409a029b71ee6e [file] [log] [blame]
Jeff Sharkey83fdc992020-10-13 19:50:30 -06001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Akhilesh Sanikop972a5382024-04-01 15:56:19 +053014#include <fcntl.h>
15#include <sys/stat.h>
16#include <unistd.h>
Jeff Sharkey83fdc992020-10-13 19:50:30 -060017
18#include "diskio.h"
19
20using namespace std;
21
22int DiskIO::OpenForRead(const unsigned char* data, size_t size) {
23 this->data = data;
24 this->size = size;
25 this->off = 0;
26 this->isOpen = 1;
27 this->openForWrite = 0;
28 return 1;
29}
30
Akhilesh Sanikop972a5382024-04-01 15:56:19 +053031void DiskIO::MakeRealName(void) { this->realFilename = this->userFilename; }
Jeff Sharkey83fdc992020-10-13 19:50:30 -060032
33int DiskIO::OpenForRead(void) {
Akhilesh Sanikop972a5382024-04-01 15:56:19 +053034 struct stat64 st;
35
36 if (this->isOpen) {
37 if (this->openForWrite) {
38 Close();
39 } else {
40 return 1;
41 }
42 }
43
44 this->fd = open(realFilename.c_str(), O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH);
45 if (this->fd == -1) {
46 this->realFilename = this->userFilename = "";
47 } else {
48 if (fstat64(fd, &st) == 0) {
49 if (!(S_ISDIR(st.st_mode) || S_ISFIFO(st.st_mode) ||
50 S_ISSOCK(st.st_mode))) {
51 this->isOpen = 1;
52 }
53 }
54 }
55 return this->isOpen;
Jeff Sharkey83fdc992020-10-13 19:50:30 -060056}
57
58int DiskIO::OpenForWrite(void) {
Akhilesh Sanikop972a5382024-04-01 15:56:19 +053059 if ((this->isOpen) && (this->openForWrite)) {
Jeff Sharkey83fdc992020-10-13 19:50:30 -060060 return 1;
Akhilesh Sanikop972a5382024-04-01 15:56:19 +053061 }
62
63 Close();
64 this->fd = open(realFilename.c_str(), O_WRONLY | O_CREAT,
65 S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
66 if (fd >= 0) {
67 this->isOpen = 1;
68 this->openForWrite = 1;
69 }
70 return this->isOpen;
Jeff Sharkey83fdc992020-10-13 19:50:30 -060071}
72
73void DiskIO::Close(void) {
Akhilesh Sanikop972a5382024-04-01 15:56:19 +053074 if (this->isOpen) {
75 close(this->fd);
76 }
77 this->isOpen = 0;
78 this->openForWrite = 0;
Jeff Sharkey83fdc992020-10-13 19:50:30 -060079}
80
81int DiskIO::GetBlockSize(void) {
82 return 512;
83}
84
85int DiskIO::GetPhysBlockSize(void) {
86 return 512;
87}
88
89uint32_t DiskIO::GetNumHeads(void) {
90 return 255;
91}
92
93uint32_t DiskIO::GetNumSecsPerTrack(void) {
94 return 63;
95}
96
97int DiskIO::DiskSync(void) {
98 return 1;
99}
100
101int DiskIO::Seek(uint64_t sector) {
Akhilesh Sanikop972a5382024-04-01 15:56:19 +0530102 int retval = 1;
103 off_t seekTo = sector * static_cast<uint64_t>(GetBlockSize());
104
105 if (!isOpen) {
106 if (OpenForRead() != 1) {
107 retval = 0;
Jeff Sharkey83fdc992020-10-13 19:50:30 -0600108 }
Akhilesh Sanikop972a5382024-04-01 15:56:19 +0530109 }
110
111 if (isOpen && seekTo < this->size) {
112 off_t sought = lseek64(fd, seekTo, SEEK_SET);
113 if (sought != seekTo) {
114 retval = 0;
115 }
116 }
117
118 if (retval) {
119 this->off = seekTo;
120 }
121
122 return retval;
Jeff Sharkey83fdc992020-10-13 19:50:30 -0600123}
124
125int DiskIO::Read(void* buffer, int numBytes) {
Akhilesh Sanikop972a5382024-04-01 15:56:19 +0530126 int actualBytes = 0;
127 if (this->size > this->off) {
128 actualBytes = std::min(static_cast<int>(this->size - this->off), numBytes);
Jeff Sharkey83fdc992020-10-13 19:50:30 -0600129 memcpy(buffer, this->data + this->off, actualBytes);
Akhilesh Sanikop972a5382024-04-01 15:56:19 +0530130 }
Jeff Sharkey83fdc992020-10-13 19:50:30 -0600131 return actualBytes;
132}
133
Akhilesh Sanikop972a5382024-04-01 15:56:19 +0530134int DiskIO::Write(void *buffer, int numBytes) {
135 int blockSize, i, numBlocks, retval = 0;
136 char *tempSpace;
137
138 if ((!this->isOpen) || (!this->openForWrite)) {
139 OpenForWrite();
140 }
141
142 if (this->isOpen) {
143 blockSize = GetBlockSize();
144 if (numBytes <= blockSize) {
145 numBlocks = 1;
146 tempSpace = new char[blockSize];
147 } else {
148 numBlocks = numBytes / blockSize;
149 if ((numBytes % blockSize) != 0)
150 numBlocks++;
151 tempSpace = new char[numBlocks * blockSize];
152 }
153 if (tempSpace == NULL) {
154 return 0;
155 }
156
157 memcpy(tempSpace, buffer, numBytes);
158 for (i = numBytes; i < numBlocks * blockSize; i++) {
159 tempSpace[i] = 0;
160 }
161 retval = write(fd, tempSpace, numBlocks * blockSize);
162
163 if (((numBlocks * blockSize) != numBytes) && (retval > 0))
164 retval = numBytes;
165
166 delete[] tempSpace;
167 }
168 return retval;
Jeff Sharkey83fdc992020-10-13 19:50:30 -0600169}
170
171uint64_t DiskIO::DiskSize(int *) {
172 return this->size / GetBlockSize();
173}