summaryrefslogtreecommitdiff
path: root/support.cc
diff options
context:
space:
mode:
authorsrs5694 <srs5694@users.sourceforge.net>2010-01-05 00:14:19 -0500
committersrs5694 <srs5694@users.sourceforge.net>2010-01-05 00:14:19 -0500
commit1e09372bca227ffbfb9dda48160826d8f63ce9bb (patch)
treefc7985fba7adc24d200c15355126e422ecea912b /support.cc
parent5d58fe0ea12c9c727c8a970c8e1ac08ea7fbe05f (diff)
downloadsgdisk-1e09372bca227ffbfb9dda48160826d8f63ce9bb.tar.gz
Early support for larger-than-512-byte sectors and even earlier support
for sgdisk program. (The latter is just proof-of-concept at this point; it doesn't do anything useful.)
Diffstat (limited to 'support.cc')
-rw-r--r--support.cc88
1 files changed, 79 insertions, 9 deletions
diff --git a/support.cc b/support.cc
index 9763dbf..8ab9a2e 100644
--- a/support.cc
+++ b/support.cc
@@ -223,10 +223,10 @@ int GetBlockSize(int fd) {
} // if
} // if
- if (result != 512) {
+/* if (result != 512) {
printf("\aWARNING! Sector size is not 512 bytes! This program is likely to ");
printf("misbehave!\nProceed at your own risk!\n\n");
- } // if
+ } // if */
return (result);
} // GetBlockSize()
@@ -244,9 +244,12 @@ int FindAlignment(int fd) {
err = -1;
#endif
- if (err < 0) {
- result = 8;
- } else {
+ if (err < 0) { // ioctl didn't work; have to guess....
+ if (GetBlockSize(fd) == 512)
+ result = 8; // play it safe; align for 4096-byte sectors
+ else
+ result = 1; // unusual sector size; assume it's the real physical size
+ } else { // ioctl worked; compute alignment
result = physicalSectorSize / GetBlockSize(fd);
} // if/else
return result;
@@ -501,7 +504,9 @@ uint64_t disksize(int fd, int *err) {
else
sectors = (b >> 9);
} // if
-
+ // Unintuitively, the above returns values in 512-byte blocks, no
+ // matter what the underlying device's block size. Correct for this....
+ sectors /= (GetBlockSize(fd) / 512);
#endif
#endif
@@ -517,7 +522,72 @@ uint64_t disksize(int fd, int *err) {
sectors = bytes / UINT64_C(512);
} // if
} // if
-// sectors = 25000000;
-// printf("Returning bogus sector size: %d\n", sectors);
return sectors;
-}
+} // disksize()
+
+// A variant on the standard read() function. Done to work around
+// limitations in FreeBSD concerning the matching of the sector
+// size with the number of bytes read
+int myRead(int fd, char* buffer, int numBytes) {
+ int blockSize = 512, i, numBlocks, retval;
+ char* tempSpace;
+
+ // Compute required space and allocate memory
+ blockSize = GetBlockSize(fd);
+ if (numBytes <= blockSize) {
+ numBlocks = 1;
+ tempSpace = (char*) malloc(blockSize);
+ } else {
+ numBlocks = numBytes / blockSize;
+ if ((numBytes % blockSize) != 0) numBlocks++;
+ tempSpace = (char*) malloc(numBlocks * blockSize);
+ } // if/else
+
+ // Read the data into temporary space, then copy it to buffer
+ retval = read(fd, tempSpace, numBlocks * blockSize);
+ for (i = 0; i < numBytes; i++) {
+ buffer[i] = tempSpace[i];
+ } // for
+
+ // Adjust the return value, if necessary....
+ if (((numBlocks * blockSize) != numBytes) && (retval > 0))
+ retval = numBytes;
+
+ free(tempSpace);
+ return retval;
+} // myRead()
+
+// A variant on the standard write() function. Done to work around
+// limitations in FreeBSD concerning the matching of the sector
+// size with the number of bytes read
+int myWrite(int fd, char* buffer, int numBytes) {
+ int blockSize = 512, i, numBlocks, retval;
+ char* tempSpace;
+
+ // Compute required space and allocate memory
+ blockSize = GetBlockSize(fd);
+ if (numBytes <= blockSize) {
+ numBlocks = 1;
+ tempSpace = (char*) malloc(blockSize);
+ } else {
+ numBlocks = numBytes / blockSize;
+ if ((numBytes % blockSize) != 0) numBlocks++;
+ tempSpace = (char*) malloc(numBlocks * blockSize);
+ } // if/else
+
+ // Copy the data to my own buffer, then write it
+ for (i = 0; i < numBytes; i++) {
+ tempSpace[i] = buffer[i];
+ } // for
+ for (i = numBytes; i < numBlocks * blockSize; i++) {
+ tempSpace[i] = 0;
+ } // for
+ retval = write(fd, tempSpace, numBlocks * blockSize);
+
+ // Adjust the return value, if necessary....
+ if (((numBlocks * blockSize) != numBytes) && (retval > 0))
+ retval = numBytes;
+
+ free(tempSpace);
+ return retval;
+} // myRead()