merge mainline into hints

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-12-23 18:49:00 +01:00
commit 17785932df
448 changed files with 43023 additions and 10176 deletions

View file

@ -43,6 +43,7 @@
#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. */
@ -93,10 +94,16 @@ struct hd_geometry
# include <sys/disk.h> /* DIOCGMEDIASIZE */
# include <sys/param.h>
# include <sys/sysctl.h>
# include <sys/mount.h>
#include <libgeom.h>
# define MAJOR(dev) major(dev)
# define FLOPPY_MAJOR 2
#endif
#if defined (__sun__)
# include <sys/dkio.h>
#endif
#if defined(__APPLE__)
# include <sys/disk.h>
#endif
@ -105,9 +112,7 @@ struct hd_geometry
# include <libdevmapper.h>
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <libgeom.h>
#elif defined(__NetBSD__)
#if defined(__NetBSD__)
# define HAVE_DIOCGDINFO
# include <sys/ioctl.h>
# include <sys/disklabel.h> /* struct disklabel */
@ -187,6 +192,27 @@ configure_device_driver (int fd)
}
#endif /* defined(__NetBSD__) */
static int
unescape_cmp (const char *a, const char *b_escaped)
{
while (*a || *b_escaped)
{
if (*b_escaped == '\\' && b_escaped[1] != 0)
b_escaped++;
if (*a < *b_escaped)
return -1;
if (*a > *b_escaped)
return +1;
a++;
b_escaped++;
}
if (*a)
return +1;
if (*b_escaped)
return -1;
return 0;
}
static int
find_grub_drive (const char *name)
{
@ -195,7 +221,7 @@ find_grub_drive (const char *name)
if (name)
{
for (i = 0; i < ARRAY_SIZE (map); i++)
if (map[i].drive && ! strcmp (map[i].drive, name))
if (map[i].drive && unescape_cmp (map[i].drive, name) == 0)
return i;
}
@ -215,10 +241,14 @@ find_free_slot (void)
}
static int
grub_util_biosdisk_iterate (int (*hook) (const char *name))
grub_util_biosdisk_iterate (int (*hook) (const char *name),
grub_disk_pull_t pull)
{
unsigned i;
if (pull != GRUB_DISK_PULL_NONE)
return 0;
for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
if (map[i].drive && hook (map[i].drive))
return 1;
@ -226,6 +256,98 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name))
return 0;
}
#if !defined(__MINGW32__)
grub_uint64_t
grub_util_get_fd_sectors (int fd, unsigned *log_secsize)
{
# if defined(__NetBSD__)
struct disklabel label;
# elif defined (__sun__)
struct dk_minfo minfo;
#else
unsigned long long nr;
# endif
unsigned sector_size, log_sector_size;
struct stat st;
if (fstat (fd, &st) < 0)
grub_util_error (_("fstat failed"));
#if defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) \
|| defined (__sun__)
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) || defined (__sun__)
if (! S_ISCHR (st.st_mode))
# else
if (! S_ISBLK (st.st_mode))
# endif
goto fail;
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
if (ioctl (fd, DIOCGMEDIASIZE, &nr))
# elif defined(__APPLE__)
if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr))
# elif defined(__NetBSD__)
configure_device_driver (fd);
if (ioctl (fd, DIOCGDINFO, &label) == -1)
# elif defined (__sun__)
if (!ioctl (fd, DKIOCGMEDIAINFO, &minfo))
# else
if (ioctl (fd, BLKGETSIZE64, &nr))
# endif
goto fail;
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
if (ioctl (fd, DIOCGSECTORSIZE, &sector_size))
goto fail;
# elif defined(__sun__)
sector_size = minfo.dki_lbsize;
# elif defined(__NetBSD__)
sector_size = label.d_secsize;
# else
if (ioctl (fd, BLKSSZGET, &sector_size))
goto fail;
# endif
if (sector_size & (sector_size - 1) || !sector_size)
goto fail;
for (log_sector_size = 0;
(1 << log_sector_size) < sector_size;
log_sector_size++);
if (log_secsize)
*log_secsize = log_sector_size;
# if defined (__APPLE__)
return nr;
# elif defined(__NetBSD__)
return label.d_secperunit;
# elif defined (__sun__)
return minfo.dki_capacity;
# else
if (nr & ((1 << log_sector_size) - 1))
grub_util_error (_("unaligned device size"));
return (nr >> log_sector_size);
# endif
fail:
/* In GNU/Hurd, stat() will return the right size. */
#elif !defined (__GNU__)
# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal."
#endif
sector_size = 512;
log_sector_size = 9;
if (log_secsize)
*log_secsize = 9;
return st.st_size >> 9;
}
#endif
static grub_err_t
grub_util_biosdisk_open (const char *name, grub_disk_t disk)
{
@ -254,7 +376,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
size = grub_util_get_disk_size (map[drive].device);
if (size % 512)
grub_util_error ("unaligned device size");
grub_util_error (_("unaligned device size"));
disk->total_sectors = size >> 9;
@ -262,77 +384,30 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
return GRUB_ERR_NONE;
}
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
#else
{
# if defined(__NetBSD__)
struct disklabel label;
# else
unsigned long long nr;
# endif
int fd;
fd = open (map[drive].device, O_RDONLY);
if (fd == -1)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device);
disk->total_sectors = grub_util_get_fd_sectors (fd, &disk->log_sector_size);
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
# else
if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode))
# endif
{
close (fd);
goto fail;
}
data->is_disk = 1;
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
if (ioctl (fd, DIOCGMEDIASIZE, &nr))
# elif defined(__APPLE__)
if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr))
# elif defined(__NetBSD__)
configure_device_driver (fd);
if (ioctl (fd, DIOCGDINFO, &label) == -1)
# else
if (ioctl (fd, BLKGETSIZE64, &nr))
# endif
{
close (fd);
goto fail;
}
data->is_disk = 1;
close (fd);
# if defined (__APPLE__)
disk->total_sectors = nr;
# elif defined(__NetBSD__)
disk->total_sectors = label.d_secperunit;
# else
disk->total_sectors = nr / 512;
if (nr % 512)
grub_util_error ("unaligned device size");
# endif
grub_util_info ("the size of %s is %llu", name, disk->total_sectors);
return GRUB_ERR_NONE;
}
fail:
/* In GNU/Hurd, stat() will return the right size. */
#elif !defined (__GNU__)
# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal."
#endif
if (stat (map[drive].device, &st) < 0)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot stat `%s'", map[drive].device);
disk->total_sectors = st.st_size >> GRUB_DISK_SECTOR_BITS;
grub_util_info ("the size of %s is %lu", name, disk->total_sectors);
return GRUB_ERR_NONE;
}
int
@ -353,11 +428,13 @@ grub_util_device_is_mapped (const char *dev)
#endif /* HAVE_DEVICE_MAPPER */
}
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
/* FIXME: geom actually gives us the whole container hierarchy.
It can be used more efficiently than this. */
static void
follow_geom_up (const char *name, grub_disk_addr_t *off_out, char **name_out)
void
grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **name_out)
{
struct gmesh mesh;
struct gclass *class;
@ -368,13 +445,13 @@ follow_geom_up (const char *name, grub_disk_addr_t *off_out, char **name_out)
error = geom_gettree (&mesh);
if (error != 0)
grub_util_error ("couldn't open geom");
grub_util_error (_("couldn't open geom"));
LIST_FOREACH (class, &mesh.lg_class, lg_class)
if (strcasecmp (class->lg_name, "part") == 0)
break;
if (!class)
grub_util_error ("couldn't open geom part");
grub_util_error (_("couldn't open geom part"));
LIST_FOREACH (geom, &class->lg_geom, lg_geom)
{
@ -387,7 +464,7 @@ follow_geom_up (const char *name, grub_disk_addr_t *off_out, char **name_out)
struct gconfig *config;
grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name);
follow_geom_up (name_tmp, &off, name_out);
grub_util_follow_gpart_up (name_tmp, &off, name_out);
free (name_tmp);
LIST_FOREACH (config, &provider->lg_config, lg_config)
if (strcasecmp (config->lg_name, "start") == 0)
@ -410,16 +487,19 @@ find_partition_start (const char *dev)
grub_disk_addr_t out;
if (strncmp (dev, "/dev/", sizeof ("/dev/") - 1) != 0)
return 0;
follow_geom_up (dev + sizeof ("/dev/") - 1, &out, NULL);
grub_util_follow_gpart_up (dev + sizeof ("/dev/") - 1, &out, NULL);
return out;
}
#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined (__sun__)
static grub_disk_addr_t
find_partition_start (const char *dev)
{
int fd;
# if !defined(HAVE_DIOCGDINFO)
#ifdef __sun__
struct extpart_info pinfo;
# elif !defined(HAVE_DIOCGDINFO)
struct hd_geometry hdg;
# else /* defined(HAVE_DIOCGDINFO) */
struct disklabel label;
@ -506,7 +586,9 @@ devmapper_fail:
return 0;
}
# if !defined(HAVE_DIOCGDINFO)
#if defined(__sun__)
if (ioctl (fd, DKIOCEXTPARTINFO, &pinfo))
# elif !defined(HAVE_DIOCGDINFO)
if (ioctl (fd, HDIO_GETGEO, &hdg))
# else /* defined(HAVE_DIOCGDINFO) */
# if defined(__NetBSD__)
@ -527,7 +609,9 @@ devmapper_fail:
close (fd);
# if !defined(HAVE_DIOCGDINFO)
#ifdef __sun__
return pinfo.p_start;
# elif !defined(HAVE_DIOCGDINFO)
return hdg.start;
# else /* defined(HAVE_DIOCGDINFO) */
if (dev[0])
@ -567,6 +651,7 @@ linux_find_partition (char *dev, grub_disk_addr_t sector)
int i;
char real_dev[PATH_MAX];
struct linux_partition_cache *cache;
int missing = 0;
strcpy(real_dev, dev);
@ -575,6 +660,12 @@ linux_find_partition (char *dev, grub_disk_addr_t sector)
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;
@ -605,7 +696,13 @@ linux_find_partition (char *dev, grub_disk_addr_t sector)
fd = open (real_dev, O_RDONLY);
if (fd == -1)
continue;
{
if (missing++ < 10)
continue;
else
return 0;
}
missing = 0;
close (fd);
start = find_partition_start (real_dev);
@ -632,6 +729,37 @@ linux_find_partition (char *dev, grub_disk_addr_t sector)
}
#endif /* __linux__ */
#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 (int 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, "cannot seek `%s'", name);
}
return GRUB_ERR_NONE;
}
#else
grub_err_t
grub_util_fd_seek (int 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, "cannot seek `%s'", name);
return 0;
}
#endif
static int
open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
{
@ -784,44 +912,20 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
configure_device_driver (fd);
#endif /* defined(__NetBSD__) */
#if defined(__linux__) && (!defined(__GLIBC__) || \
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
/* Maybe libc doesn't have large file support. */
{
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) sector << GRUB_DISK_SECTOR_BITS;
if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
{
grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device);
close (fd);
return -1;
}
}
#else
{
off_t offset = (off_t) sector << GRUB_DISK_SECTOR_BITS;
if (lseek (fd, offset, SEEK_SET) != offset)
{
grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device);
close (fd);
return -1;
}
}
#endif
if (grub_util_fd_seek (fd, map[disk->id].device,
sector << disk->log_sector_size))
{
close (fd);
return -1;
}
return fd;
}
/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an
error occurs, otherwise return LEN. */
static ssize_t
nread (int fd, char *buf, size_t len)
ssize_t
grub_util_fd_read (int fd, char *buf, size_t len)
{
ssize_t size = len;
@ -904,19 +1008,20 @@ grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
sectors that are read together with the MBR in one read. It
should only remap the MBR, so we split the read in two
parts. -jochen */
if (nread (fd, buf, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE)
if (grub_util_fd_read (fd, buf, (1 << disk->log_sector_size))
!= (1 << disk->log_sector_size))
{
grub_error (GRUB_ERR_READ_ERROR, "cannot read `%s'", map[disk->id].device);
return grub_errno;
}
buf += GRUB_DISK_SECTOR_SIZE;
buf += (1 << disk->log_sector_size);
size--;
}
#endif /* __linux__ */
if (nread (fd, buf, size << GRUB_DISK_SECTOR_BITS)
!= (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
if (grub_util_fd_read (fd, buf, size << disk->log_sector_size)
!= (ssize_t) (size << disk->log_sector_size))
grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device);
return grub_errno;
@ -949,8 +1054,8 @@ grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
if (fd < 0)
return grub_errno;
if (nwrite (fd, buf, size << GRUB_DISK_SECTOR_BITS)
!= (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
if (nwrite (fd, buf, size << disk->log_sector_size)
!= (ssize_t) (size << disk->log_sector_size))
grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device);
return grub_errno;
@ -1048,18 +1153,18 @@ read_device_map (const char *dev_map)
continue;
if (*p != '(')
show_error ("No open parenthesis found");
show_error (_("No open parenthesis found"));
p++;
/* Find a free slot. */
drive = find_free_slot ();
if (drive < 0)
show_error ("Map table size exceeded");
show_error (_("Map table size exceeded"));
e = p;
p = strchr (p, ')');
if (! p)
show_error ("No close parenthesis found");
show_error (_("No close parenthesis found"));
map[drive].drive = xmalloc (p - e + sizeof ('\0'));
strncpy (map[drive].drive, e, p - e + sizeof ('\0'));
@ -1072,7 +1177,7 @@ read_device_map (const char *dev_map)
p++;
if (*p == '\0')
show_error ("No filename found");
show_error (_("No filename found"));
/* NUL-terminate the filename. */
e = p;
@ -1101,7 +1206,7 @@ read_device_map (const char *dev_map)
{
map[drive].device = xmalloc (PATH_MAX);
if (! realpath (p, map[drive].device))
grub_util_error ("cannot get the real path of `%s'", p);
grub_util_error (_("cannot get the real path of `%s'"), p);
}
else
#endif
@ -1142,25 +1247,28 @@ grub_util_biosdisk_fini (void)
static char *
make_device_name (int drive, int dos_part, int bsd_part)
{
char *ret;
char *dos_part_str = NULL;
char *bsd_part_str = NULL;
char *ret, *ptr, *end;
const char *iptr;
ret = xmalloc (strlen (map[drive].drive) * 2
+ sizeof (",XXXXXXXXXXXXXXXXXXXXXXXXXX"
",XXXXXXXXXXXXXXXXXXXXXXXXXX"));
end = (ret + strlen (map[drive].drive) * 2
+ sizeof (",XXXXXXXXXXXXXXXXXXXXXXXXXX"
",XXXXXXXXXXXXXXXXXXXXXXXXXX"));
ptr = ret;
for (iptr = map[drive].drive; *iptr; iptr++)
{
if (*iptr == ',')
*ptr++ = '\\';
*ptr++ = *iptr;
}
*ptr = 0;
if (dos_part >= 0)
dos_part_str = xasprintf (",%d", dos_part + 1);
snprintf (ptr, end - ptr, ",%d", dos_part + 1);
ptr += strlen (ptr);
if (bsd_part >= 0)
bsd_part_str = xasprintf (",%d", bsd_part + 1);
ret = xasprintf ("%s%s%s", map[drive].drive,
dos_part_str ? : "",
bsd_part_str ? : "");
if (dos_part_str)
free (dos_part_str);
if (bsd_part_str)
free (bsd_part_str);
snprintf (ptr, end - ptr, ",%d", bsd_part + 1);
return ret;
}
@ -1418,7 +1526,8 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
if (tree)
dm_tree_free (tree);
free (path);
char *ret = grub_find_device (NULL, (major << 8) | minor);
char *ret = grub_find_device ("/dev",
(major << 8) | minor);
return ret;
}
@ -1496,7 +1605,7 @@ devmapper_out:
char *out, *out2;
if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0)
return xstrdup (os_dev);
follow_geom_up (os_dev + sizeof ("/dev/") - 1, NULL, &out);
grub_util_follow_gpart_up (os_dev + sizeof ("/dev/") - 1, NULL, &out);
out2 = xasprintf ("/dev/%s", out);
free (out);
@ -1545,12 +1654,37 @@ devmapper_out:
}
return path;
#elif defined (__sun__)
char *colon = grub_strrchr (os_dev, ':');
if (grub_memcmp (os_dev, "/devices", sizeof ("/devices") - 1) == 0
&& colon)
{
char *ret = xmalloc (colon - os_dev + sizeof (":q,raw"));
grub_memcpy (ret, os_dev, colon - os_dev);
grub_memcpy (ret + (colon - os_dev), ":q,raw", sizeof (":q,raw"));
return ret;
}
else
return xstrdup (os_dev);
#else
# warning "The function `convert_system_partition_to_system_disk' might not work on your OS correctly."
return xstrdup (os_dev);
#endif
}
#if defined(__sun__)
static int
device_is_wholedisk (const char *os_dev)
{
if (grub_memcmp (os_dev, "/devices/", sizeof ("/devices/") - 1) != 0)
return 1;
if (grub_memcmp (os_dev + strlen (os_dev) - (sizeof (":q,raw") - 1),
":q,raw", (sizeof (":q,raw") - 1)) == 0)
return 1;
return 0;
}
#endif
#if defined(__linux__) || defined(__CYGWIN__)
static int
device_is_wholedisk (const char *os_dev)
@ -1627,7 +1761,10 @@ find_system_device (const char *os_dev, struct stat *st, int convert, int add)
}
if (!add)
return -1;
{
free (os_disk);
return -1;
}
if (i == ARRAY_SIZE (map))
grub_util_error (_("device count exceeds limit"));
@ -1657,6 +1794,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
{
struct stat st;
int drive;
char *sys_disk;
grub_util_info ("Looking for %s", os_dev);
if (stat (os_dev, &st) < 0)
{
@ -1674,18 +1814,22 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return 0;
}
if (grub_strcmp (os_dev,
convert_system_partition_to_system_disk (os_dev, &st)) == 0)
return make_device_name (drive, -1, -1);
sys_disk = convert_system_partition_to_system_disk (os_dev, &st);
if (grub_strcmp (os_dev, sys_disk) == 0)
{
free (sys_disk);
return make_device_name (drive, -1, -1);
}
free (sys_disk);
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) || defined (__sun__)
if (! S_ISCHR (st.st_mode))
#else
if (! S_ISBLK (st.st_mode))
#endif
return make_device_name (drive, -1, -1);
#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__sun__)
/* Linux counts partitions uniformly, whether a BSD partition or a DOS
partition, so mapping them to GRUB devices is not trivial.
@ -1725,7 +1869,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
name = make_device_name (drive, -1, -1);
# if !defined(HAVE_DIOCGDINFO)
# if !defined(HAVE_DIOCGDINFO) && !defined(__sun__)
if (MAJOR (st.st_rdev) == FLOPPY_MAJOR)
return name;
# else /* defined(HAVE_DIOCGDINFO) */
@ -1788,6 +1932,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
if (partname == NULL)
{
grub_disk_close (disk);
grub_util_info ("cannot find the partition of `%s'", os_dev);
grub_error (GRUB_ERR_BAD_DEVICE,
"cannot find the partition of `%s'", os_dev);
return 0;
@ -1851,6 +1996,9 @@ grub_util_biosdisk_is_floppy (grub_disk_t disk)
struct stat st;
int fd;
if (disk->dev != &grub_util_biosdisk_dev)
return 0;
fd = open (map[disk->id].device, O_RDONLY);
/* Shouldn't happen. */
if (fd == -1)
@ -1858,7 +2006,12 @@ grub_util_biosdisk_is_floppy (grub_disk_t disk)
/* Shouldn't happen either. */
if (fstat (fd, &st) < 0)
return 0;
{
close (fd);
return 0;
}
close (fd);
#if defined(__NetBSD__)
if (major(st.st_rdev) == RAW_FLOPPY_MAJOR)