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