Patch by Samuel Rodriguez Perez: Added support for writing Haiku
directly onto a device under FreeBSD. I messed around with the code a little (style-fixes, some refactoring) without being able to compile or test it, so be careful... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23880 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
0d83dc06e3
commit
80b2da5e53
@ -19,7 +19,7 @@
|
||||
#include <Resources.h>
|
||||
#include <TypeConstants.h>
|
||||
|
||||
// Linux support
|
||||
// Linux and FreeBSD support
|
||||
#ifdef HAIKU_HOST_PLATFORM_LINUX
|
||||
# include <ctype.h>
|
||||
# include <linux/hdreg.h>
|
||||
@ -27,7 +27,15 @@
|
||||
|
||||
# include "PartitionMap.h"
|
||||
# include "PartitionMapParser.h"
|
||||
#endif // HAIKU_HOST_PLATFORM_LINUX
|
||||
#elif HAIKU_HOST_PLATFORM_FREEBSD
|
||||
# include <ctype.h>
|
||||
# include <sys/disklabel.h>
|
||||
# include <sys/disk.h>
|
||||
# include <sys/ioctl.h>
|
||||
|
||||
# include "PartitionMap.h"
|
||||
# include "PartitionMapParser.h"
|
||||
#endif
|
||||
|
||||
|
||||
static const char *kCommandName = "makebootable";
|
||||
@ -272,13 +280,98 @@ main(int argc, const char *const *argv)
|
||||
noPartition = true;
|
||||
} else if (S_ISCHR(st.st_mode)) {
|
||||
// character special: a device or partition under BeOS
|
||||
#ifndef __BEOS__
|
||||
// or under FreeBSD
|
||||
#if !defined(__BEOS__) && !defined(HAIKU_HOST_PLATFORM_FREEBSD)
|
||||
|
||||
fprintf(stderr, "Error: Character special devices not "
|
||||
"supported on this platform.\n");
|
||||
exit(1);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAIKU_HOST_PLATFORM_FREEBSD
|
||||
|
||||
// chop off the trailing number
|
||||
int fileNameLen = strlen(fileName);
|
||||
int baseNameLen = -1;
|
||||
for (int k = fileNameLen - 1; k >= 0; k--) {
|
||||
if (!isdigit(fileName[k])) {
|
||||
baseNameLen = k + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove de 's' from 'ad2s2' slice device (partition for DOS
|
||||
// users) to get 'ad2' base device
|
||||
baseNameLen--;
|
||||
|
||||
if (baseNameLen < 0) {
|
||||
// only digits?
|
||||
fprintf(stderr, "Error: Failed to get base device name.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (baseNameLen < fileNameLen) {
|
||||
// get base device name and partition index
|
||||
char baseDeviceName[B_PATH_NAME_LENGTH];
|
||||
int partitionIndex = atoi(fileName + baseNameLen + 1);
|
||||
// Don't forget the 's' of slice :)
|
||||
memcpy(baseDeviceName, fileName, baseNameLen);
|
||||
baseDeviceName[baseNameLen] = '\0';
|
||||
|
||||
// open base device
|
||||
int baseFD = open(baseDeviceName, O_RDONLY);
|
||||
if (baseFD < 0) {
|
||||
fprintf(stderr, "Error: Failed to open \"%s\": %s\n",
|
||||
baseDeviceName, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// get device size
|
||||
int64 deviceSize;
|
||||
if (ioctl(baseFD, DIOCGMEDIASIZE, &deviceSize) == -1) {
|
||||
fprintf(stderr, "Error: Failed to get device geometry "
|
||||
"for \"%s\": %s\n", baseDeviceName,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// parse the partition map
|
||||
PartitionMapParser parser(baseFD, 0, deviceSize);
|
||||
PartitionMap map;
|
||||
error = parser.Parse(NULL, &map);
|
||||
if (error != B_OK) {
|
||||
fprintf(stderr, "Error: Parsing partition table on "
|
||||
"device \"%s\" failed: %s\n", baseDeviceName,
|
||||
strerror(error));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
close(baseFD);
|
||||
|
||||
// check the partition we are supposed to write at
|
||||
Partition *partition = map.PartitionAt(partitionIndex - 1);
|
||||
if (!partition || partition->IsEmpty()) {
|
||||
fprintf(stderr, "Error: Invalid partition index %d.\n",
|
||||
partitionIndex);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (partition->IsExtended()) {
|
||||
fprintf(stderr, "Error: Partition %d is an extended "
|
||||
"partition.\n", partitionIndex);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
partitionOffset = partition->Offset();
|
||||
|
||||
} else {
|
||||
// The given device is the base device. We'll write at
|
||||
// offset 0.
|
||||
}
|
||||
|
||||
#endif // HAIKU_HOST_PLATFORM_FREEBSD
|
||||
|
||||
} else if (S_ISBLK(st.st_mode)) {
|
||||
// block device: a device or partition under Linux
|
||||
#ifdef HAIKU_HOST_PLATFORM_LINUX
|
||||
|
@ -27,6 +27,11 @@ if $(HOST_PLATFORM) != darwin {
|
||||
strlSources = strlcpy.c strlcat.c ;
|
||||
}
|
||||
|
||||
local hostPlatformSources ;
|
||||
if $(HOST_PLATFORM) = freebsd {
|
||||
hostPlatformSources = fs_freebsd.cpp ;
|
||||
}
|
||||
|
||||
BuildPlatformSharedLibrary libroot_build.so :
|
||||
atomic.cpp
|
||||
byteorder.cpp
|
||||
@ -38,6 +43,8 @@ BuildPlatformSharedLibrary libroot_build.so :
|
||||
sem.cpp
|
||||
thread.cpp
|
||||
|
||||
$(hostPlatformSources)
|
||||
|
||||
$(strlSources)
|
||||
strnlen.c
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
/*
|
||||
* Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <BeOSBuildCompatibility.h>
|
||||
|
||||
@ -22,10 +26,28 @@
|
||||
#include "fs_descriptors.h"
|
||||
#include "NodeRef.h"
|
||||
|
||||
#if defined(HAIKU_HOST_PLATFORM_FREEBSD)
|
||||
# include "fs_freebsd.h"
|
||||
#endif
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace BPrivate;
|
||||
|
||||
|
||||
#if defined(HAIKU_HOST_PLATFORM_FREEBSD)
|
||||
# define haiku_host_platform_read haiku_freebsd_read
|
||||
# define haiku_host_platform_write haiku_freebsd_write
|
||||
# define haiku_host_platform_readv haiku_freebsd_readv
|
||||
# define haiku_host_platform_writev haiku_freebsd_writev
|
||||
#else
|
||||
# define haiku_host_platform_read read
|
||||
# define haiku_host_platform_write write
|
||||
# define haiku_host_platform_readv readv
|
||||
# define haiku_host_platform_writev writev
|
||||
#endif
|
||||
|
||||
|
||||
static status_t get_path(dev_t device, ino_t node, const char *name,
|
||||
string &path);
|
||||
|
||||
@ -583,7 +605,8 @@ _kern_read(int fd, off_t pos, void *buffer, size_t bufferSize)
|
||||
}
|
||||
|
||||
// read
|
||||
ssize_t bytesRead = read(descriptor->fd, buffer, bufferSize);
|
||||
ssize_t bytesRead = haiku_host_platform_read(descriptor->fd, buffer,
|
||||
bufferSize);
|
||||
if (bytesRead < 0)
|
||||
return errno;
|
||||
|
||||
@ -608,7 +631,8 @@ _kern_write(int fd, off_t pos, const void *buffer, size_t bufferSize)
|
||||
}
|
||||
|
||||
// read
|
||||
ssize_t bytesWritten = write(descriptor->fd, buffer, bufferSize);
|
||||
ssize_t bytesWritten = haiku_host_platform_write(descriptor->fd, buffer,
|
||||
bufferSize);
|
||||
if (bytesWritten < 0)
|
||||
return errno;
|
||||
|
||||
@ -932,7 +956,7 @@ read_pos(int fd, off_t pos, void *buffer, size_t bufferSize)
|
||||
return errno;
|
||||
|
||||
// read
|
||||
ssize_t bytesRead = read(fd, buffer, bufferSize);
|
||||
ssize_t bytesRead = haiku_host_platform_read(fd, buffer, bufferSize);
|
||||
if (bytesRead < 0) {
|
||||
errno = bytesRead;
|
||||
return -1;
|
||||
@ -949,9 +973,9 @@ write_pos(int fd, off_t pos, const void *buffer, size_t bufferSize)
|
||||
off_t result = lseek(fd, pos, SEEK_SET);
|
||||
if (result < 0)
|
||||
return errno;
|
||||
|
||||
|
||||
// read
|
||||
ssize_t bytesWritten = write(fd, buffer, bufferSize);
|
||||
ssize_t bytesWritten = haiku_host_platform_write(fd, buffer, bufferSize);
|
||||
if (bytesWritten < 0) {
|
||||
errno = bytesWritten;
|
||||
return -1;
|
||||
@ -970,7 +994,7 @@ readv_pos(int fd, off_t pos, const struct iovec *vec, size_t count)
|
||||
return errno;
|
||||
|
||||
// read
|
||||
ssize_t bytesRead = readv(fd, vec, count);
|
||||
ssize_t bytesRead = haiku_host_platform_readv(fd, vec, count);
|
||||
if (bytesRead < 0) {
|
||||
errno = bytesRead;
|
||||
return -1;
|
||||
@ -989,7 +1013,7 @@ writev_pos(int fd, off_t pos, const struct iovec *vec, size_t count)
|
||||
return errno;
|
||||
|
||||
// read
|
||||
ssize_t bytesWritten = writev(fd, vec, count);
|
||||
ssize_t bytesWritten = haiku_host_platform_writev(fd, vec, count);
|
||||
if (bytesWritten < 0) {
|
||||
errno = bytesWritten;
|
||||
return -1;
|
||||
|
254
src/build/libroot/fs_freebsd.cpp
Normal file
254
src/build/libroot/fs_freebsd.cpp
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright 2008, Samuel Rodriguez Perez, samuelgaliza@gmail.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "fs_freebsd.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
// Read and write operations in FreeBSD only work on devices block by block.
|
||||
|
||||
ssize_t
|
||||
haiku_freebsd_read(int fd, void *buf, size_t nbytes)
|
||||
{
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) != 0)
|
||||
return -1;
|
||||
|
||||
if (S_ISREG(st.st_mode))
|
||||
return read(fd, buf, nbytes); // Is a file! Good :)
|
||||
|
||||
int sectorSize;
|
||||
if (ioctl(fd, DIOCGSECTORSIZE, §orSize) == -1)
|
||||
sectorSize = 512; // If fail, hardcode to 512 for now
|
||||
|
||||
off_t cur = lseek(fd, 0, SEEK_CUR);
|
||||
if (cur == -1)
|
||||
perror("lseek 1");
|
||||
|
||||
off_t seekDiff = (sectorSize - (cur % sectorSize)) % sectorSize;
|
||||
off_t nbytesDiff = (nbytes - seekDiff) % sectorSize;
|
||||
|
||||
if (seekDiff == 0 && nbytesDiff == 0) {
|
||||
// Not needed but this saves malloc and free operations
|
||||
return read(fd, buf, nbytes);
|
||||
|
||||
} else if (cur % sectorSize + nbytes <= sectorSize) {
|
||||
// Read complete in only a block
|
||||
char* tmpBlock = (char*)malloc(sectorSize);
|
||||
|
||||
// Put at start of the block
|
||||
off_t sdCur = lseek(fd, -(cur % sectorSize), SEEK_CUR);
|
||||
if (sdCur == -1)
|
||||
perror("lseek oneblock");
|
||||
if (read(fd, tmpBlock, sectorSize) == -1)
|
||||
perror("read oneblock");
|
||||
memcpy((char*)buf, tmpBlock + cur % sectorSize, nbytes);
|
||||
// repos at byte offset of latest wrote block
|
||||
if (lseek(fd, -sectorSize + (cur % sectorSize) + nbytes, SEEK_CUR)
|
||||
== -1) {
|
||||
perror("lseek2 oneblock");
|
||||
}
|
||||
|
||||
free(tmpBlock);
|
||||
|
||||
return nbytes;
|
||||
|
||||
} else {
|
||||
// Needs to write more than a block
|
||||
|
||||
char* tmpBlock = (char*)malloc(sectorSize);
|
||||
|
||||
// First block if seek isn't
|
||||
if (seekDiff > 0) {
|
||||
// read entire block at 0 pos
|
||||
if (lseek(fd, -(sectorSize - seekDiff), SEEK_CUR) == -1)
|
||||
perror("lseek seekDiff");
|
||||
off_t sdCur = lseek(fd,0,SEEK_CUR);
|
||||
if (sdCur == -1)
|
||||
perror("lseek2 seekDiff");
|
||||
if (read(fd, tmpBlock, sectorSize) == -1 )
|
||||
perror("read seekDiff");
|
||||
// alter content
|
||||
memcpy(buf, tmpBlock + (sectorSize - seekDiff), seekDiff);
|
||||
|
||||
}
|
||||
|
||||
// Blocks between
|
||||
if ((nbytes - seekDiff) >= sectorSize) {
|
||||
if (read(fd, ((char*)buf) + seekDiff, nbytes - seekDiff - nbytesDiff) == -1)
|
||||
perror("read between");
|
||||
}
|
||||
|
||||
// Last block if overflow
|
||||
if (nbytesDiff > 0 ) {
|
||||
|
||||
off_t sdCur = lseek(fd, 0, SEEK_CUR);
|
||||
if (sdCur == -1)
|
||||
perror("lseek last");
|
||||
if (read(fd, tmpBlock, sectorSize) == -1)
|
||||
perror("read last");
|
||||
memcpy(((char*)buf) + nbytes - nbytesDiff, tmpBlock, nbytesDiff);
|
||||
// repos at byte offset of latest wrote block
|
||||
if (lseek(fd, -(sectorSize - nbytesDiff), SEEK_CUR) == -1)
|
||||
perror("lseek2 last");
|
||||
}
|
||||
|
||||
free(tmpBlock);
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
haiku_freebsd_write(int fd, const void *buf, size_t nbytes)
|
||||
{
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) != 0)
|
||||
return -1;
|
||||
|
||||
if (S_ISREG(st.st_mode))
|
||||
return write(fd, buf, nbytes); // Is a file! Good :)
|
||||
|
||||
int sectorSize;
|
||||
if (ioctl(fd, DIOCGSECTORSIZE, §orSize) == -1)
|
||||
sectorSize = 512; // If fail, hardcode do 512 for now
|
||||
|
||||
off_t cur = lseek(fd, 0, SEEK_CUR);
|
||||
if (cur == -1)
|
||||
perror("lseek 1");
|
||||
|
||||
off_t seekDiff = (sectorSize - (cur % sectorSize)) % sectorSize;
|
||||
off_t nbytesDiff = (nbytes - seekDiff) % sectorSize;
|
||||
|
||||
if (seekDiff == 0 && nbytesDiff == 0) {
|
||||
// Not needed but this saves malloc and free operations
|
||||
return write(fd, buf, nbytes);
|
||||
|
||||
} else if (cur % sectorSize + nbytes <= sectorSize) {
|
||||
// Write complete in only a block
|
||||
char* tmpBlock = (char*)malloc(sectorSize);
|
||||
|
||||
// Put at start of the block
|
||||
off_t sdCur = lseek(fd, -(cur % sectorSize), SEEK_CUR);
|
||||
if (sdCur == -1)
|
||||
perror("lseek oneblock");
|
||||
if (pread(fd, tmpBlock, sectorSize, sdCur) == -1)
|
||||
perror("pread oneblock");
|
||||
memcpy(tmpBlock + cur % sectorSize, (char*)buf, nbytes);
|
||||
if (write(fd, tmpBlock, sectorSize) == -1)
|
||||
perror("write oneblock");
|
||||
// repos at byte offset of latest written block
|
||||
if (lseek(fd, -sectorSize + (cur % sectorSize) + nbytes, SEEK_CUR) == -1)
|
||||
perror("lseek2 oneblock");
|
||||
|
||||
free(tmpBlock);
|
||||
|
||||
return nbytes;
|
||||
|
||||
} else {
|
||||
// Needs to write more than a block
|
||||
|
||||
char* tmpBlock = (char*)malloc(sectorSize);
|
||||
|
||||
// First block if seek isn't
|
||||
if (seekDiff > 0) {
|
||||
// read entire block at 0 pos
|
||||
if (lseek(fd, -(sectorSize - seekDiff), SEEK_CUR) == -1)
|
||||
perror("lseek seekDiff");
|
||||
off_t sdCur = lseek(fd, 0, SEEK_CUR);
|
||||
if (sdCur == -1)
|
||||
perror("lseek2 seekDiff");
|
||||
if (pread(fd, tmpBlock, sectorSize, sdCur) == -1 )
|
||||
perror("pread seekDiff");
|
||||
// alter content
|
||||
memcpy(tmpBlock + (sectorSize - seekDiff), buf, seekDiff);
|
||||
if (write(fd, tmpBlock, sectorSize)==-1)
|
||||
perror("write seekDiff");
|
||||
|
||||
}
|
||||
|
||||
// Blocks between
|
||||
if ((nbytes - seekDiff) >= sectorSize) {
|
||||
if (write(fd, ((char*)buf) + seekDiff, nbytes - seekDiff - nbytesDiff) == -1)
|
||||
perror("write between");
|
||||
}
|
||||
|
||||
// Last block if overflow
|
||||
if (nbytesDiff > 0) {
|
||||
|
||||
off_t sdCur = lseek(fd, 0, SEEK_CUR);
|
||||
if (sdCur == -1)
|
||||
perror("lseek last");
|
||||
if (pread(fd, tmpBlock, sectorSize, sdCur) == -1)
|
||||
perror("pread last");
|
||||
memcpy(tmpBlock, ((char*)buf) + nbytes - nbytesDiff, nbytesDiff);
|
||||
if (write(fd, tmpBlock, sectorSize) == -1)
|
||||
perror("write last");
|
||||
// repos at byte offset of latest wrote block
|
||||
if (lseek(fd, -(sectorSize - nbytesDiff), SEEK_CUR) == -1)
|
||||
perror("lseek2 last");
|
||||
}
|
||||
|
||||
free(tmpBlock);
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
haiku_freebsd_readv(int fd, const iovec *vecs, size_t count)
|
||||
{
|
||||
ssize_t bytesRead = 0;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ssize_t currentRead = haiku_freebsd_read(fd, vecs[i].iov_base,
|
||||
vecs[i].iov_len);
|
||||
|
||||
if (currentRead < 0)
|
||||
return bytesRead > 0 ? bytesRead : -1;
|
||||
|
||||
bytesRead += currentRead;
|
||||
|
||||
if ((size_t)currentRead != vecs[i].iov_len)
|
||||
break;
|
||||
}
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
haiku_freebsd_writev(int fd, const struct iovec *vecs, size_t count)
|
||||
{
|
||||
ssize_t bytesWritten = 0;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ssize_t written = haiku_freebsd_write(fd, vecs[i].iov_base,
|
||||
vecs[i].iov_len);
|
||||
|
||||
if (written < 0)
|
||||
return bytesWritten > 0 ? bytesWritten : -1;
|
||||
|
||||
bytesWritten += written;
|
||||
|
||||
if ((size_t)written != vecs[i].iov_len)
|
||||
break;
|
||||
}
|
||||
|
||||
return bytesWritten;
|
||||
}
|
17
src/build/libroot/fs_freebsd.h
Normal file
17
src/build/libroot/fs_freebsd.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef FS_FREEBSD_H
|
||||
#define FS_FREEBSD_H
|
||||
|
||||
#include <sys/uio.h>
|
||||
|
||||
|
||||
ssize_t haiku_freebsd_read(int fd, void *buf, size_t nbytes);
|
||||
ssize_t haiku_freebsd_write(int fd, const void *buf, size_t nbytes);
|
||||
ssize_t haiku_freebsd_readv(int fd, const iovec *vecs, size_t count);
|
||||
ssize_t haiku_freebsd_writev(int fd, const struct iovec *vecs, size_t count);
|
||||
|
||||
|
||||
#endif // FS_FREEBSD_H
|
@ -41,7 +41,11 @@ fssh_readv(int fd, const struct fssh_iovec *vector, fssh_size_t count)
|
||||
if (!prepare_iovecs(vector, count, systemVecs))
|
||||
return -1;
|
||||
|
||||
return readv(fd, systemVecs, count);
|
||||
#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
|
||||
return readv(fd, systemVecs, count);
|
||||
#else
|
||||
return readv_pos(fd, lseek(fd, 0, SEEK_CUR), systemVecs, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -64,7 +68,11 @@ fssh_writev(int fd, const struct fssh_iovec *vector, fssh_size_t count)
|
||||
if (!prepare_iovecs(vector, count, systemVecs))
|
||||
return -1;
|
||||
|
||||
return writev(fd, systemVecs, count);
|
||||
#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
|
||||
return writev(fd, systemVecs, count);
|
||||
#else
|
||||
return writev_pos(fd, lseek(fd, 0, SEEK_CUR), systemVecs, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,6 +22,9 @@
|
||||
# if defined(HAIKU_HOST_PLATFORM_FREEBSD) \
|
||||
|| defined(HAIKU_HOST_PLATFORM_DARWIN)
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/disk.h>
|
||||
# include <sys/disklabel.h>
|
||||
# else
|
||||
// the (POSIX) correct place of definition for ioctl()
|
||||
# include <stropts.h>
|
||||
@ -195,9 +198,56 @@ fssh_ioctl(int fd, unsigned long op, ...)
|
||||
} else
|
||||
error = errno;
|
||||
|
||||
#elif HAIKU_HOST_PLATFORM_FREEBSD
|
||||
{
|
||||
// FreeBSD has not block devices
|
||||
|
||||
struct stat status;
|
||||
|
||||
if (fstat(fd, &status) == 0) {
|
||||
struct disklabel disklabel;
|
||||
off_t mediaSize;
|
||||
|
||||
memset(&disklabel,0,sizeof disklabel);
|
||||
|
||||
// Ignore errors, this way we can use memory devices (md%d)
|
||||
ioctl(fd, DIOCGSECTORSIZE, &disklabel.d_secsize);
|
||||
ioctl(fd, DIOCGFWSECTORS, &disklabel.d_nsectors);
|
||||
ioctl(fd, DIOCGFWHEADS, &disklabel.d_ntracks);
|
||||
ioctl(fd, DIOCGMEDIASIZE, &mediaSize);
|
||||
|
||||
if (disklabel.d_nsectors == 0) {
|
||||
// Seems to be a md device, then ioctls returns lots of
|
||||
// zeroes and hardcode some defaults
|
||||
disklabel.d_nsectors = 64;
|
||||
disklabel.d_ntracks = 16;
|
||||
}
|
||||
|
||||
disklabel.d_secperunit = mediaSize / disklabel.d_secsize;
|
||||
disklabel.d_ncylinders = mediaSize / disklabel.d_secsize
|
||||
/ disklabel.d_nsectors
|
||||
/ disklabel.d_ntracks;
|
||||
|
||||
geometry->head_count = disklabel.d_ntracks;
|
||||
geometry->cylinder_count = disklabel.d_ncylinders;
|
||||
geometry->sectors_per_track = disklabel.d_nsectors;
|
||||
|
||||
geometry->bytes_per_sector = disklabel.d_secsize;
|
||||
// FreeBSD supports device_type flag as disklabel.d_type,
|
||||
// for now we harcod it to B_DISK.
|
||||
geometry->device_type = FSSH_B_DISK;
|
||||
geometry->removable = disklabel.d_flags & D_REMOVABLE > 0;
|
||||
// read_only?
|
||||
geometry->read_only = false;
|
||||
// FreeBSD does not support write_once flag.
|
||||
geometry->write_once = false;
|
||||
error = B_OK;
|
||||
} else
|
||||
error = errno;
|
||||
}
|
||||
#else
|
||||
// Not implemented for this platform, i.e. we won't be able to
|
||||
// deal with block devices.
|
||||
// deal with disk devices.
|
||||
#endif
|
||||
|
||||
break;
|
||||
@ -245,7 +295,11 @@ fssh_ioctl(int fd, unsigned long op, ...)
|
||||
fssh_ssize_t
|
||||
fssh_read(int fd, void *buffer, fssh_size_t count)
|
||||
{
|
||||
return read(fd, buffer, count);
|
||||
#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
|
||||
return read(fd, buffer, count);
|
||||
#else
|
||||
return read_pos(fd, lseek(fd, 0, SEEK_CUR), buffer, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -259,7 +313,11 @@ fssh_read_pos(int fd, fssh_off_t pos, void *buffer, fssh_size_t count)
|
||||
fssh_ssize_t
|
||||
fssh_write(int fd, const void *buffer, fssh_size_t count)
|
||||
{
|
||||
return write(fd, buffer, count);
|
||||
#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
|
||||
return write(fd, buffer, count);
|
||||
#else
|
||||
return write_pos(fd, lseek(fd, 0, SEEK_CUR), buffer, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user