Move OS-dependent files to grub-core/osdep and document it.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-10-08 17:30:22 +02:00
parent a5b0365ab2
commit 672fa55e81
30 changed files with 39 additions and 30 deletions

View file

@ -1,74 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
# include <sys/disk.h>
grub_uint64_t
grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
{
unsigned long long nr;
unsigned sector_size, log_sector_size;
if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr))
return -1;
if (ioctl (fd, DKIOCGETBLOCKSIZE, &sector_size))
return -1;
if (sector_size & (sector_size - 1) || !sector_size)
return -1;
for (log_sector_size = 0;
(1 << log_sector_size) < sector_size;
log_sector_size++);
if (log_secsize)
*log_secsize = log_sector_size;
return nr << log_sector_size;
}
void
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
{
}

View file

@ -1,506 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <dos/dos.h>
#include <dos/filesystem.h>
#include <dos/exall.h>
#include <proto/dos.h>
#include <devices/hardblocks.h>
#include <devices/newstyle.h>
#include <proto/exec.h>
#include <proto/utility.h>
#include <proto/partition.h>
#include <devices/trackdisk.h>
#include <exec/errors.h>
#define BOUNCE_SIZE 1048576
static ULONG *bounce;
char *
canonicalize_file_name (const char *path)
{
char *ret;
BPTR lck;
const char *p;
p = strchr (path, ':');
if (p && !p[1])
return xstrdup (path);
ret = xmalloc (2048);
lck = Lock ((const unsigned char *) path, SHARED_LOCK);
if (!lck || !NameFromLock (lck, (unsigned char *) ret, 2040))
{
free (ret);
ret = xstrdup (path);
}
if (lck)
UnLock (lck);
return ret;
}
static grub_uint64_t
grub_util_get_fd_size_volume (grub_util_fd_t fd __attribute__ ((unused)),
const char *dev,
unsigned *log_secsize)
{
struct DriveGeometry *geo;
LONG err;
unsigned sector_size, log_sector_size;
if (!bounce)
bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
if (!bounce)
grub_util_error ("out of memory");
fd->ioreq->iotd_Req.io_Command = TD_GETGEOMETRY;
fd->ioreq->iotd_Req.io_Length = sizeof (*geo);
fd->ioreq->iotd_Req.io_Data = bounce;
fd->ioreq->iotd_Req.io_Offset = 0;
fd->ioreq->iotd_Req.io_Actual = 0;
err = DoIO ((struct IORequest *) fd->ioreq);
if (err)
{
grub_util_info ("I/O failed with error %d, IoErr=%d", (int)err, (int) IoErr ());
return -1;
}
geo = (struct DriveGeometry *) bounce;
sector_size = geo->dg_SectorSize;
if (sector_size & (sector_size - 1) || !sector_size)
return -1;
for (log_sector_size = 0;
(1 << log_sector_size) < sector_size;
log_sector_size++);
if (log_secsize)
*log_secsize = log_sector_size;
return (grub_uint64_t) geo->dg_TotalSectors * (grub_uint64_t) geo->dg_SectorSize;
}
static grub_uint64_t
grub_util_get_fd_size_file (grub_util_fd_t fd,
const char *dev __attribute__ ((unused)),
unsigned *log_secsize)
{
off_t oo, ro;
*log_secsize = 9;
/* FIXME: support 64-bit offsets. */
oo = lseek (fd->fd, 0, SEEK_CUR);
ro = lseek (fd->fd, 0, SEEK_END);
lseek (fd->fd, oo, SEEK_SET);
return ro;
}
grub_err_t
grub_util_fd_seek (grub_util_fd_t fd, const char *name, grub_uint64_t off)
{
switch (fd->type)
{
case GRUB_UTIL_FD_FILE:
if (lseek (fd->fd, 0, SEEK_SET) == (off_t) -1)
return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
name, strerror (errno));
fd->off = off;
return 0;
case GRUB_UTIL_FD_DISK:
fd->off = off;
return 0;
}
return 0;
}
grub_util_fd_t
grub_util_fd_open (const char *dev, int flg)
{
grub_util_fd_t ret = xmalloc (sizeof (*ret));
const char *p, *p1, *p2;
char *tmp;
IPTR unit = 0;
ULONG flags = 0;
ret->off = 0;
if (dev[0] == '\0')
{
free (ret);
return NULL;
}
p = strchr (dev, ':');
if (!p || p[1])
{
ret->type = GRUB_UTIL_FD_FILE;
ret->fd = open (dev, flg);
if (ret->fd < 0)
{
free (ret);
return NULL;
}
return ret;
}
p1 = strchr (dev, '/');
if (!p1)
p1 = p;
else
{
unit = grub_strtoul (p1 + 1, (char **) &p2, 16);
if (p2 && *p2 == '/')
flags = grub_strtoul (p2 + 1, 0, 16);
}
ret->mp = CreateMsgPort();
if (!ret->mp)
{
free (ret);
return NULL;
}
ret->ioreq = (struct IOExtTD *) CreateIORequest(ret->mp,
sizeof(struct IOExtTD));
if (!ret->ioreq)
{
free (ret);
DeleteMsgPort (ret->mp);
return NULL;
}
tmp = xmalloc (p1 - dev + 1);
memcpy (tmp, dev, p1 - dev);
tmp[p1 - dev] = '\0';
ret->type = GRUB_UTIL_FD_DISK;
ret->is_floppy = (strcmp (tmp, TD_NAME) == 0);
ret->is_64 = 1;
if (OpenDevice ((unsigned char *) tmp, unit, (struct IORequest *) ret->ioreq, flags))
{
free (tmp);
free (ret);
DeleteMsgPort (ret->mp);
return NULL;
}
free (tmp);
return ret;
}
static ssize_t
grub_util_fd_read_file (grub_util_fd_t fd, char *buf, size_t len)
{
ssize_t size = len;
while (len)
{
ssize_t ret = read (fd->fd, buf, len);
if (ret <= 0)
{
if (errno == EINTR)
continue;
else
return ret;
}
fd->off += ret;
len -= ret;
buf += ret;
}
return size;
}
/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an
error occurs, otherwise return LEN. */
static ssize_t
grub_util_fd_write_file (grub_util_fd_t fd, const char *buf, size_t len)
{
ssize_t size = len;
while (len)
{
ssize_t ret = write (fd->fd, buf, len);
if (ret <= 0)
{
if (errno == EINTR)
continue;
else
return ret;
}
fd->off += ret;
len -= ret;
buf += ret;
}
return size;
}
static void
stop_motor (grub_util_fd_t fd)
{
if (!fd->is_floppy)
return;
fd->ioreq->iotd_Req.io_Command = TD_MOTOR;
fd->ioreq->iotd_Req.io_Length = 0;
fd->ioreq->iotd_Req.io_Data = 0;
fd->ioreq->iotd_Req.io_Offset = 0;
fd->ioreq->iotd_Req.io_Actual = 0;
DoIO ((struct IORequest *) fd->ioreq);
}
static ssize_t
grub_util_fd_read_volume (grub_util_fd_t fd, char *buf, size_t len)
{
grub_uint64_t adj = 0;
if (!bounce)
bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
if (!bounce)
grub_util_error ("out of memory");
while (len)
{
size_t cr = len;
LONG err;
if (cr > BOUNCE_SIZE)
cr = BOUNCE_SIZE;
retry:
if (fd->is_64)
fd->ioreq->iotd_Req.io_Command = NSCMD_TD_READ64;
else
fd->ioreq->iotd_Req.io_Command = CMD_READ;
fd->ioreq->iotd_Req.io_Length = cr;
fd->ioreq->iotd_Req.io_Data = bounce;
fd->ioreq->iotd_Req.io_Offset = fd->off & 0xFFFFFFFF;
fd->ioreq->iotd_Req.io_Actual = fd->off >> 32;
err = DoIO ((struct IORequest *) fd->ioreq);
if (err == IOERR_NOCMD && fd->is_64)
{
fd->is_64 = 0;
goto retry;
}
if (err)
{
grub_util_info ("I/O failed with error %d, IoErr=%d", (int)err, (int) IoErr ());
stop_motor (fd);
return -1;
}
memcpy (buf, bounce, cr);
adj += cr;
len -= cr;
buf += cr;
}
fd->off += adj;
stop_motor (fd);
return adj;
}
static ssize_t
grub_util_fd_write_volume (grub_util_fd_t fd, const char *buf, size_t len)
{
grub_uint64_t adj = 0;
if (!bounce)
bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
if (!bounce)
grub_util_error ("out of memory");
while (len)
{
size_t cr = len;
LONG err;
if (cr > BOUNCE_SIZE)
cr = BOUNCE_SIZE;
retry:
if (fd->is_64)
fd->ioreq->iotd_Req.io_Command = NSCMD_TD_WRITE64;
else
fd->ioreq->iotd_Req.io_Command = CMD_WRITE;
fd->ioreq->iotd_Req.io_Length = cr;
fd->ioreq->iotd_Req.io_Data = bounce;
fd->ioreq->iotd_Req.io_Offset = fd->off & 0xFFFFFFFF;
fd->ioreq->iotd_Req.io_Actual = fd->off >> 32;
memcpy (bounce, buf, cr);
err = DoIO ((struct IORequest *) fd->ioreq);
if (err == IOERR_NOCMD && fd->is_64)
{
fd->is_64 = 0;
goto retry;
}
if (err)
{
grub_util_info ("I/O failed with error %d", err);
stop_motor (fd);
return -1;
}
adj += cr;
len -= cr;
buf += cr;
}
fd->off += adj;
stop_motor (fd);
return adj;
}
ssize_t
grub_util_fd_read (grub_util_fd_t fd, char *buf, size_t len)
{
switch (fd->type)
{
case GRUB_UTIL_FD_FILE:
return grub_util_fd_read_file (fd, buf, len);
case GRUB_UTIL_FD_DISK:
return grub_util_fd_read_volume (fd, buf, len);
}
return -1;
}
ssize_t
grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len)
{
switch (fd->type)
{
case GRUB_UTIL_FD_FILE:
return grub_util_fd_write_file (fd, buf, len);
case GRUB_UTIL_FD_DISK:
return grub_util_fd_write_volume (fd, buf, len);
}
return -1;
}
grub_uint64_t
grub_util_get_fd_size (grub_util_fd_t fd,
const char *dev,
unsigned *log_secsize)
{
switch (fd->type)
{
case GRUB_UTIL_FD_FILE:
return grub_util_get_fd_size_file (fd, dev, log_secsize);
case GRUB_UTIL_FD_DISK:
return grub_util_get_fd_size_volume (fd, dev, log_secsize);
}
return -1;
}
void
grub_util_fd_close (grub_util_fd_t fd)
{
switch (fd->type)
{
case GRUB_UTIL_FD_FILE:
close (fd->fd);
return;
case GRUB_UTIL_FD_DISK:
CloseDevice ((struct IORequest *) fd->ioreq);
DeleteIORequest((struct IORequest *) fd->ioreq);
DeleteMsgPort (fd->mp);
return;
}
}
static void
grub_util_fd_sync_volume (grub_util_fd_t fd)
{
fd->ioreq->iotd_Req.io_Command = CMD_UPDATE;
fd->ioreq->iotd_Req.io_Length = 0;
fd->ioreq->iotd_Req.io_Data = 0;
fd->ioreq->iotd_Req.io_Offset = 0;
fd->ioreq->iotd_Req.io_Actual = 0;
DoIO ((struct IORequest *) fd->ioreq);
}
void
grub_util_fd_sync (grub_util_fd_t fd)
{
switch (fd->type)
{
case GRUB_UTIL_FD_FILE:
fsync (fd->fd);
return;
case GRUB_UTIL_FD_DISK:
grub_util_fd_sync_volume (fd);
return;
}
}
void
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
{
}
void
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
{
}
const char *
grub_util_fd_strerror (void)
{
static char buf[201];
LONG err = IoErr ();
if (!err)
return _("Success");
memset (buf, '\0', sizeof (buf));
Fault (err, (const unsigned char *) "", (STRPTR) buf, sizeof (buf));
if (buf[0] == ':')
return buf + 1;
return buf;
}

View file

@ -1,63 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
grub_int64_t
grub_util_get_fd_size_os (grub_util_fd_t fd __attribute__ ((unused)),
const char *name __attribute__ ((unused)),
unsigned *log_secsize __attribute__ ((unused)))
{
# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal."
return -1;
}
void
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
{
}
void
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
{
}

View file

@ -1,115 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
# include <sys/ioctl.h>
# include <sys/disklabel.h> /* struct disklabel */
# include <sys/disk.h> /* struct dkwedge_info */
# ifdef HAVE_GETRAWPARTITION
# include <util.h> /* getrawpartition */
# endif /* HAVE_GETRAWPARTITION */
# if defined(__NetBSD__)
# include <sys/fdio.h>
# endif
# if defined(__OpenBSD__)
# include <sys/dkio.h>
# endif
#if defined(__NetBSD__)
/* Adjust device driver parameters. This function should be called just
after successfully opening the device. For now, it simply prevents the
floppy driver from retrying operations on failure, as otherwise the
driver takes a while to abort when there is no floppy in the drive. */
void
grub_hostdisk_configure_device_driver (grub_util_fd_t fd)
{
struct stat st;
if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
return;
if (major(st.st_rdev) == RAW_FLOPPY_MAJOR)
{
int floppy_opts;
if (ioctl (fd, FDIOCGETOPTS, &floppy_opts) == -1)
return;
floppy_opts |= FDOPT_NORETRY;
if (ioctl (fd, FDIOCSETOPTS, &floppy_opts) == -1)
return;
}
}
#else
void
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
{
}
#endif
grub_int64_t
grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
{
struct disklabel label;
unsigned sector_size, log_sector_size;
grub_hostdisk_configure_device_driver (fd);
if (ioctl (fd, DIOCGDINFO, &label) == -1)
return -1;
sector_size = label.d_secsize;
if (sector_size & (sector_size - 1) || !sector_size)
return -1;
for (log_sector_size = 0;
(1 << log_sector_size) < sector_size;
log_sector_size++);
if (log_secsize)
*log_secsize = log_sector_size;
return (grub_uint64_t) label.d_secperunit << log_sector_size;
}
void
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
{
}

View file

@ -1,194 +0,0 @@
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#ifdef HAVE_DEVICE_MAPPER
# include <libdevmapper.h>
static void device_mapper_null_log (int level __attribute__ ((unused)),
const char *file __attribute__ ((unused)),
int line __attribute__ ((unused)),
int dm_errno __attribute__ ((unused)),
const char *f __attribute__ ((unused)),
...)
{
}
int
grub_device_mapper_supported (void)
{
static int supported = -1;
if (supported == -1)
{
struct dm_task *dmt;
/* Suppress annoying log messages. */
dm_log_with_errno_init (&device_mapper_null_log);
dmt = dm_task_create (DM_DEVICE_VERSION);
supported = (dmt != NULL);
if (dmt)
dm_task_destroy (dmt);
/* Restore the original logger. */
dm_log_with_errno_init (NULL);
}
return supported;
}
int
grub_util_device_is_mapped (const char *dev)
{
struct stat st;
if (!grub_device_mapper_supported ())
return 0;
if (stat (dev, &st) < 0)
return 0;
return dm_is_dm_major (major (st.st_rdev));
}
int
grub_util_get_dm_node_linear_info (const char *dev,
int *maj, int *min,
grub_disk_addr_t *st)
{
struct dm_task *dmt;
void *next = NULL;
uint64_t length, start;
char *target, *params;
char *ptr;
int major = 0, minor = 0;
int first = 1;
grub_disk_addr_t partstart = 0;
const char *node_uuid;
while (1)
{
dmt = dm_task_create(DM_DEVICE_TABLE);
if (!dmt)
break;
if (! (first ? dm_task_set_name (dmt, dev)
: dm_task_set_major_minor (dmt, major, minor, 0)))
{
dm_task_destroy (dmt);
break;
}
dm_task_no_open_count(dmt);
if (!dm_task_run(dmt))
{
dm_task_destroy (dmt);
break;
}
node_uuid = dm_task_get_uuid (dmt);
if (node_uuid && (strncmp (node_uuid, "LVM-", 4) == 0
|| strncmp (node_uuid, "mpath-", 6) == 0
|| strncmp (node_uuid, "DMRAID-", 7) == 0))
{
dm_task_destroy (dmt);
break;
}
next = dm_get_next_target(dmt, next, &start, &length,
&target, &params);
if (grub_strcmp (target, "linear") != 0)
{
dm_task_destroy (dmt);
break;
}
major = grub_strtoul (params, &ptr, 10);
if (grub_errno)
{
dm_task_destroy (dmt);
grub_errno = GRUB_ERR_NONE;
return 0;
}
if (*ptr != ':')
{
dm_task_destroy (dmt);
return 0;
}
ptr++;
minor = grub_strtoul (ptr, &ptr, 10);
if (grub_errno)
{
grub_errno = GRUB_ERR_NONE;
dm_task_destroy (dmt);
return 0;
}
if (*ptr != ' ')
{
dm_task_destroy (dmt);
return 0;
}
ptr++;
partstart += grub_strtoull (ptr, &ptr, 10);
if (grub_errno)
{
grub_errno = GRUB_ERR_NONE;
dm_task_destroy (dmt);
return 0;
}
dm_task_destroy (dmt);
first = 0;
if (!dm_is_dm_major (major))
break;
}
if (first)
return 0;
if (maj)
*maj = major;
if (min)
*min = minor;
if (st)
*st = partstart;
return 1;
}
#else
int
grub_util_device_is_mapped (const char *dev __attribute__ ((unused)))
{
return 0;
}
int
grub_util_get_dm_node_linear_info (const char *dev __attribute__ ((unused)),
int *maj __attribute__ ((unused)),
int *min __attribute__ ((unused)),
grub_disk_addr_t *st __attribute__ ((unused)))
{
return 0;
}
#endif

View file

@ -1,85 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
# include <sys/disk.h> /* DIOCGMEDIASIZE */
# include <sys/param.h>
# include <sys/sysctl.h>
# include <sys/mount.h>
# include <libgeom.h>
void
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
{
}
grub_int64_t
grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
{
unsigned long long nr;
unsigned sector_size, log_sector_size;
if (ioctl (fd, DIOCGMEDIASIZE, &nr))
return -1;
if (ioctl (fd, DIOCGSECTORSIZE, &sector_size))
return -1;
if (sector_size & (sector_size - 1) || !sector_size)
return -1;
for (log_sector_size = 0;
(1 << log_sector_size) < sector_size;
log_sector_size++);
if (log_secsize)
*log_secsize = log_sector_size;
if (nr & (sector_size - 1))
grub_util_error ("%s", _("unaligned device size"));
return nr;
}
void
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
{
}

View file

@ -1,151 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <hurd.h>
#include <hurd/lookup.h>
#include <hurd/fs.h>
#include <sys/mman.h>
void
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
{
}
int
grub_util_hurd_get_disk_info (const char *dev, grub_uint32_t *secsize, grub_disk_addr_t *offset,
grub_disk_addr_t *size, char **parent)
{
file_t file;
mach_port_t *ports;
int *ints;
loff_t *offsets;
char *data;
error_t err;
mach_msg_type_number_t num_ports = 0, num_ints = 0, num_offsets = 0, data_len = 0;
file = file_name_lookup (dev, 0, 0);
if (file == MACH_PORT_NULL)
return 0;
err = file_get_storage_info (file,
&ports, &num_ports,
&ints, &num_ints,
&offsets, &num_offsets,
&data, &data_len);
if (num_ints < 1)
grub_util_error (_("Storage info for `%s' does not include type"), dev);
if (ints[0] != STORAGE_DEVICE)
grub_util_error (_("`%s' is not a local disk"), dev);
if (num_offsets != 2)
grub_util_error (_("Storage info for `%s' does indicate neither plain partition nor plain disk"), dev);
if (parent)
{
*parent = NULL;
if (num_ints >= 5)
{
size_t len = ints[4];
if (len > data_len)
len = data_len;
*parent = xmalloc (len+1);
memcpy (*parent, data, len);
(*parent)[len] = '\0';
}
}
if (offset)
*offset = offsets[0];
if (size)
*size = offsets[1];
if (secsize)
*secsize = ints[2];
if (ports && num_ports > 0)
{
mach_msg_type_number_t i;
for (i = 0; i < num_ports; i++)
{
mach_port_t port = ports[i];
if (port != MACH_PORT_NULL)
mach_port_deallocate (mach_task_self(), port);
}
munmap ((caddr_t) ports, num_ports * sizeof (*ports));
}
if (ints && num_ints > 0)
munmap ((caddr_t) ints, num_ints * sizeof (*ints));
if (offsets && num_offsets > 0)
munmap ((caddr_t) offsets, num_offsets * sizeof (*offsets));
if (data && data_len > 0)
munmap (data, data_len);
mach_port_deallocate (mach_task_self (), file);
return 1;
}
grub_int64_t
grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
{
grub_uint32_t sector_size;
grub_disk_addr_t size;
unsigned log_sector_size;
if (!grub_util_hurd_get_disk_info (name, &sector_size, NULL, &size, NULL))
return -1;
if (sector_size & (sector_size - 1) || !sector_size)
return -1;
for (log_sector_size = 0;
(1 << log_sector_size) < sector_size;
log_sector_size++);
if (log_secsize)
*log_secsize = log_sector_size;
return size << log_sector_size;
}
void
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
{
}

View file

@ -1,362 +0,0 @@
/* hostdisk.c - emulate biosdisk */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
# include <sys/ioctl.h> /* ioctl */
# include <sys/mount.h>
# ifndef BLKFLSBUF
# define BLKFLSBUF _IO (0x12,97) /* flush buffer cache */
# endif /* ! BLKFLSBUF */
# include <sys/ioctl.h> /* ioctl */
# ifndef HDIO_GETGEO
# define HDIO_GETGEO 0x0301 /* get device geometry */
/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
defined. */
struct hd_geometry
{
unsigned char heads;
unsigned char sectors;
unsigned short cylinders;
unsigned long start;
};
# endif /* ! HDIO_GETGEO */
# ifndef BLKGETSIZE64
# define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size */
# endif /* ! BLKGETSIZE64 */
grub_int64_t
grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
{
unsigned long long nr;
unsigned sector_size, log_sector_size;
if (ioctl (fd, BLKGETSIZE64, &nr))
return -1;
if (ioctl (fd, BLKSSZGET, &sector_size))
return -1;
if (sector_size & (sector_size - 1) || !sector_size)
return -1;
for (log_sector_size = 0;
(1 << log_sector_size) < sector_size;
log_sector_size++);
if (log_secsize)
*log_secsize = log_sector_size;
if (nr & ((1 << log_sector_size) - 1))
grub_util_error ("%s", _("unaligned device size"));
return nr;
}
grub_disk_addr_t
grub_util_find_partition_start_os (const char *dev)
{
grub_util_fd_t fd;
struct hd_geometry hdg;
fd = open (dev, O_RDONLY);
if (fd == -1)
{
grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot open `%s': %s"),
dev, strerror (errno));
return 0;
}
if (ioctl (fd, HDIO_GETGEO, &hdg))
{
grub_error (GRUB_ERR_BAD_DEVICE,
"cannot get disk geometry of `%s'", dev);
close (fd);
return 0;
}
close (fd);
return hdg.start;
}
/* Cache of partition start sectors for each disk. */
struct linux_partition_cache
{
struct linux_partition_cache *next;
struct linux_partition_cache **prev;
char *dev;
unsigned long start;
int partno;
};
struct linux_partition_cache *linux_partition_cache_list;
/* Check if we have devfs support. */
static int
have_devfs (void)
{
static int dev_devfsd_exists = -1;
if (dev_devfsd_exists < 0)
{
struct stat st;
dev_devfsd_exists = stat ("/dev/.devfsd", &st) == 0;
}
return dev_devfsd_exists;
}
int
grub_hostdisk_linux_find_partition (char *dev, grub_disk_addr_t sector)
{
size_t len = strlen (dev);
const char *format;
char *p;
int i;
char real_dev[PATH_MAX];
struct linux_partition_cache *cache;
int missing = 0;
strcpy(real_dev, dev);
if (have_devfs () && strcmp (real_dev + len - 5, "/disc") == 0)
{
p = real_dev + len - 4;
format = "part%d";
}
else if (strncmp (real_dev, "/dev/disk/by-id/",
sizeof ("/dev/disk/by-id/") - 1) == 0)
{
p = real_dev + len;
format = "-part%d";
}
else if (real_dev[len - 1] >= '0' && real_dev[len - 1] <= '9')
{
p = real_dev + len;
format = "p%d";
}
else
{
p = real_dev + len;
format = "%d";
}
for (cache = linux_partition_cache_list; cache; cache = cache->next)
{
if (strcmp (cache->dev, dev) == 0 && cache->start == sector)
{
sprintf (p, format, cache->partno);
strcpy (dev, real_dev);
return 1;
}
}
for (i = 1; i < 10000; i++)
{
grub_util_fd_t fd;
grub_disk_addr_t start;
sprintf (p, format, i);
fd = open (real_dev, O_RDONLY);
if (fd == -1)
{
if (missing++ < 10)
continue;
else
return 0;
}
missing = 0;
close (fd);
if (!grub_util_device_is_mapped (real_dev)
|| !grub_util_get_dm_node_linear_info (real_dev, 0, 0, &start))
start = grub_util_find_partition_start_os (real_dev);
/* We don't care about errors here. */
grub_errno = GRUB_ERR_NONE;
if (start == sector)
{
struct linux_partition_cache *new_cache_item;
new_cache_item = xmalloc (sizeof *new_cache_item);
new_cache_item->dev = xstrdup (dev);
new_cache_item->start = start;
new_cache_item->partno = i;
grub_list_push (GRUB_AS_LIST_P (&linux_partition_cache_list),
GRUB_AS_LIST (new_cache_item));
strcpy (dev, real_dev);
return 1;
}
}
return 0;
}
void
grub_hostdisk_flush_initial_buffer (const char *os_dev)
{
grub_util_fd_t fd;
struct stat st;
fd = open (os_dev, O_RDONLY);
if (fd >= 0 && fstat (fd, &st) >= 0 && S_ISBLK (st.st_mode))
ioctl (fd, BLKFLSBUF, 0);
if (fd >= 0)
close (fd);
}
int
grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags,
grub_disk_addr_t *max)
{
grub_util_fd_t fd;
struct grub_util_hostdisk_data *data = disk->data;
*max = ~0ULL;
#ifdef O_LARGEFILE
flags |= O_LARGEFILE;
#endif
#ifdef O_SYNC
flags |= O_SYNC;
#endif
#ifdef O_FSYNC
flags |= O_FSYNC;
#endif
#ifdef O_BINARY
flags |= O_BINARY;
#endif
/* Linux has a bug that the disk cache for a whole disk is not consistent
with the one for a partition of the disk. */
{
int is_partition = 0;
char dev[PATH_MAX];
grub_disk_addr_t part_start = 0;
part_start = grub_partition_get_start (disk->partition);
strcpy (dev, grub_util_biosdisk_get_osdev (disk));
if (disk->partition
&& strncmp (dev, "/dev/", 5) == 0)
{
if (sector >= part_start)
is_partition = grub_hostdisk_linux_find_partition (dev, part_start);
else
*max = part_start - sector;
}
reopen:
if (data->dev && strcmp (data->dev, dev) == 0 &&
data->access_mode == (flags & O_ACCMODE))
{
grub_dprintf ("hostdisk", "reusing open device `%s'\n", dev);
fd = data->fd;
}
else
{
free (data->dev);
data->dev = 0;
if (data->fd != -1)
{
if (data->access_mode == O_RDWR || data->access_mode == O_WRONLY)
{
fsync (data->fd);
if (data->is_disk)
ioctl (data->fd, BLKFLSBUF, 0);
}
close (data->fd);
data->fd = -1;
}
/* Open the partition. */
grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev);
fd = open (dev, flags);
if (fd < 0)
{
grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot open `%s': %s"),
dev, strerror (errno));
return -1;
}
data->dev = xstrdup (dev);
data->access_mode = (flags & O_ACCMODE);
data->fd = fd;
if (data->is_disk)
ioctl (data->fd, BLKFLSBUF, 0);
}
if (is_partition)
{
*max = grub_util_get_fd_size (fd, dev, 0);
*max >>= disk->log_sector_size;
if (sector - part_start >= *max)
{
*max = disk->partition->len - (sector - part_start);
if (*max == 0)
*max = ~0ULL;
is_partition = 0;
strcpy (dev, grub_util_biosdisk_get_osdev (disk));
goto reopen;
}
sector -= part_start;
*max -= sector;
}
}
if (grub_util_fd_seek (fd, grub_util_biosdisk_get_osdev (disk),
sector << disk->log_sector_size))
{
close (fd);
return -1;
}
return fd;
}

View file

@ -1,20 +0,0 @@
#ifdef __linux__
#include "hostdisk_linux.c"
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include "hostdisk_freebsd.c"
#elif defined(__NetBSD__) || defined(__OpenBSD__)
#include "hostdisk_bsd.c"
#elif defined(__APPLE__)
#include "hostdisk_apple.c"
#elif defined(__sun__)
#include "hostdisk_sun.c"
#elif defined(__GNU__)
#include "hostdisk_hurd.c"
#elif defined(__CYGWIN__) || defined(__MINGW32__)
#include "hostdisk_windows.c"
#elif defined(__AROS__)
#include "hostdisk_aros.c"
#else
# warning "No hostdisk OS-specific functions is available for your system. Device detection may not work properly."
#include "hostdisk_basic.c"
#endif

View file

@ -1,78 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
# include <sys/dkio.h>
grub_int64_t
grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
{
struct dk_minfo minfo;
unsigned sector_size, log_sector_size;
if (!ioctl (fd, DKIOCGMEDIAINFO, &minfo))
return -1;
sector_size = minfo.dki_lbsize;
if (sector_size & (sector_size - 1) || !sector_size)
return -1;
for (log_sector_size = 0;
(1 << log_sector_size) < sector_size;
log_sector_size++);
if (log_secsize)
*log_secsize = log_sector_size;
return minfo.dki_capacity << log_sector_size;
}
void
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
{
}
void
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
{
}

View file

@ -1,208 +0,0 @@
/* hostdisk.c - emulate biosdisk */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#if !defined (__CYGWIN__) && !defined (__MINGW32__) && !defined (__AROS__)
#ifdef __linux__
# include <sys/ioctl.h> /* ioctl */
# include <sys/mount.h>
# if !defined(__GLIBC__) || \
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
/* Maybe libc doesn't have large file support. */
# include <linux/unistd.h> /* _llseek */
# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
# ifndef BLKFLSBUF
# define BLKFLSBUF _IO (0x12,97) /* flush buffer cache */
# endif /* ! BLKFLSBUF */
#endif /* __linux__ */
grub_uint64_t
grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
{
struct stat st;
grub_int64_t ret = -1;
if (fstat (fd, &st) < 0)
/* TRANSLATORS: "stat" comes from the name of POSIX function. */
grub_util_error (_("cannot stat `%s': %s"), name, strerror (errno));
#if GRUB_DISK_DEVS_ARE_CHAR
if (S_ISCHR (st.st_mode))
#else
if (S_ISBLK (st.st_mode))
#endif
ret = grub_util_get_fd_size_os (fd, name, log_secsize);
if (ret != -1LL)
return ret;
if (log_secsize)
*log_secsize = 9;
return st.st_size;
}
#if defined(__linux__) && (!defined(__GLIBC__) || \
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
/* Maybe libc doesn't have large file support. */
grub_err_t
grub_util_fd_seek (grub_util_fd_t fd, const char *name, grub_uint64_t off)
{
loff_t offset, result;
static int _llseek (uint filedes, ulong hi, ulong lo,
loff_t *res, uint wh);
_syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
loff_t *, res, uint, wh);
offset = (loff_t) off;
if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
name, strerror (errno));
return GRUB_ERR_NONE;
}
#else
grub_err_t
grub_util_fd_seek (grub_util_fd_t fd, const char *name, grub_uint64_t off)
{
off_t offset = (off_t) off;
if (lseek (fd, offset, SEEK_SET) != offset)
return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
name, strerror (errno));
return 0;
}
#endif
/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an
error occurs, otherwise return LEN. */
ssize_t
grub_util_fd_read (grub_util_fd_t fd, char *buf, size_t len)
{
ssize_t size = len;
while (len)
{
ssize_t ret = read (fd, buf, len);
if (ret <= 0)
{
if (errno == EINTR)
continue;
else
return ret;
}
len -= ret;
buf += ret;
}
return size;
}
/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an
error occurs, otherwise return LEN. */
ssize_t
grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len)
{
ssize_t size = len;
while (len)
{
ssize_t ret = write (fd, buf, len);
if (ret <= 0)
{
if (errno == EINTR)
continue;
else
return ret;
}
len -= ret;
buf += ret;
}
return size;
}
grub_util_fd_t
grub_util_fd_open (const char *os_dev, int flags)
{
return open (os_dev, flags);
}
const char *
grub_util_fd_strerror (void)
{
return strerror (errno);
}
void
grub_util_fd_sync (grub_util_fd_t fd)
{
fsync (fd);
}
void
grub_util_fd_close (grub_util_fd_t fd)
{
close (fd);
}
char *
canonicalize_file_name (const char *path)
{
#if defined (PATH_MAX)
char *ret;
ret = xmalloc (PATH_MAX);
if (!realpath (path, ret))
return NULL;
return ret;
#else
return realpath (path, NULL);
#endif
}
#endif

View file

@ -1,257 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <grub/util/windows.h>
#include <grub/charset.h>
#include <windows.h>
#include <winioctl.h>
#ifdef __CYGWIN__
LPTSTR
grub_util_get_windows_path (const char *path)
{
LPTSTR winpath;
winpath = xmalloc (sizeof (winpath[0]) * PATH_MAX);
if (cygwin_conv_path ((sizeof (winpath[0]) == 1 ? CCP_POSIX_TO_WIN_A
: CCP_POSIX_TO_WIN_W) | CCP_ABSOLUTE, path, winpath,
sizeof (winpath[0]) * PATH_MAX))
grub_util_error ("%s", _("cygwin_conv_path() failed"));
return winpath;
}
#else
LPTSTR
grub_util_get_windows_path (const char *path)
{
char *fpa;
const char *fp;
LPTSTR ret;
fp = fpa = xmalloc (PATH_MAX);
if (!_fullpath (fpa, path, PATH_MAX))
fp = path;
#if SIZEOF_TCHAR == 1
ret = xstrdup (fp);
#elif SIZEOF_TCHAR == 2
size_t ssz = strlen (fp);
size_t tsz = 2 * (GRUB_MAX_UTF16_PER_UTF8 * ssz + 1);
ret = xmalloc (tsz);
tsz = grub_utf8_to_utf16 (ret, tsz, (const grub_uint8_t *) fp, ssz, NULL);
ret[tsz] = 0;
#else
#error SIZEOF_TCHAR
#error "Unsupported TCHAR size"
#endif
free (fpa);
return ret;
}
#endif
grub_uint64_t
grub_util_get_fd_size (grub_util_fd_t hd, const char *name_in,
unsigned *log_secsize)
{
grub_int64_t size = -1LL;
int log_sector_size = 9;
LPTSTR name = grub_util_get_windows_path (name_in);
if (log_secsize)
*log_secsize = log_sector_size;
if (((name[0] == '/') || (name[0] == '\\')) &&
((name[1] == '/') || (name[1] == '\\')) &&
((name[2] == '.') || (name[2] == '?')) &&
((name[3] == '/') || (name[3] == '\\')))
{
DWORD nr;
DISK_GEOMETRY g;
if (! DeviceIoControl (hd, IOCTL_DISK_GET_DRIVE_GEOMETRY,
0, 0, &g, sizeof (g), &nr, 0))
goto fail;
size = g.Cylinders.QuadPart;
size *= g.TracksPerCylinder * g.SectorsPerTrack * g.BytesPerSector;
for (log_sector_size = 0;
(1 << log_sector_size) < g.BytesPerSector;
log_sector_size++);
}
else
{
ULARGE_INTEGER s;
s.LowPart = GetFileSize (hd, &s.HighPart);
size = s.QuadPart;
}
fail:
if (log_secsize)
*log_secsize = log_sector_size;
free (name);
return size;
}
void
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
{
}
void
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
{
}
grub_err_t
grub_util_fd_seek (grub_util_fd_t fd, const char *name, grub_uint64_t off)
{
LARGE_INTEGER offset;
offset.QuadPart = off;
if (!SetFilePointerEx (fd, offset, NULL, FILE_BEGIN))
return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
name, strerror (errno));
return 0;
}
grub_util_fd_t
grub_util_fd_open (const char *os_dev, int flags)
{
DWORD flg = 0;
LPTSTR dev = grub_util_get_windows_path (os_dev);
grub_util_fd_t ret;
if (flags & O_WRONLY)
flg |= GENERIC_WRITE;
if (flags & O_RDONLY)
flg |= GENERIC_READ;
flg = GENERIC_READ;
ret = CreateFile (dev, flg, FILE_SHARE_READ | FILE_SHARE_WRITE,
0, OPEN_EXISTING, 0, 0);
free (dev);
grub_util_info ("handle = %p", ret);
return ret;
}
ssize_t
grub_util_fd_read (grub_util_fd_t fd, char *buf, size_t len)
{
DWORD real_read;
if (!ReadFile(fd, buf, len, &real_read, NULL))
{
grub_util_info ("read err %x", (int) GetLastError ());
return -1;
}
grub_util_info ("successful read");
return real_read;
}
ssize_t
grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len)
{
DWORD real_read;
if (!WriteFile(fd, buf, len, &real_read, NULL))
{
grub_util_info ("write err %x", (int) GetLastError ());
return -1;
}
grub_util_info ("successful write");
return real_read;
}
void
grub_util_fd_sync (grub_util_fd_t fd)
{
FlushFileBuffers (fd);
}
void
grub_util_fd_close (grub_util_fd_t fd)
{
CloseHandle (fd);
}
const char *
grub_util_fd_strerror (void)
{
DWORD err;
static TCHAR tbuf[1024];
err = GetLastError ();
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, err,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
tbuf, ARRAY_SIZE (tbuf), NULL);
#if SIZEOF_TCHAR == 1
return (char *) tbuf;
#elif SIZEOF_TCHAR == 2
static grub_uint8_t buf[ARRAY_SIZE (tbuf) * GRUB_MAX_UTF8_PER_UTF16 + 1];
*grub_utf16_to_utf8 (buf, tbuf, ARRAY_SIZE (tbuf)) = '\0';
return (char *) buf;
#else
#error "Unsupported TCHAR size"
#endif
}
char *
canonicalize_file_name (const char *path)
{
char *ret;
ret = xmalloc (PATH_MAX);
#ifndef __CYGWIN__
if (!_fullpath (ret, path, PATH_MAX))
return NULL;
#else
if (!realpath (path, ret))
return NULL;
#endif
return ret;
}