# define DEV_CYGDRIVE_MAJOR 98
#endif
+#ifdef __GNU__
+#include <hurd.h>
+#include <hurd/lookup.h>
+#include <hurd/fs.h>
+#endif
+
#include <grub/util/misc.h>
#include <grub/util/hostdisk.h>
#include <grub/util/getroot.h>
char *
grub_guess_root_device (const char *dir)
{
- struct stat st;
char *os_dev;
+#ifdef __GNU__
+ 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;
+ size_t name_len;
+
+ file = file_name_lookup (dir, 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", dir);
+ if (ints[0] != STORAGE_DEVICE)
+ grub_util_error ("Filesystem of `%s' is not stored on local disk", dir);
+
+ if (num_ints < 5)
+ grub_util_error ("Storage info for `%s' does not include name", dir);
+ name_len = ints[4];
+ if (name_len < data_len)
+ grub_util_error ("Bogus name length for storage info for `%s'", dir);
+ if (data[name_len - 1] != '\0')
+ grub_util_error ("Storage name for `%s' not NUL-terminated", dir);
+
+ os_dev = xmalloc (strlen ("/dev/") + data_len);
+ memcpy (os_dev, "/dev/", strlen ("/dev/"));
+ memcpy (os_dev + strlen ("/dev/"), data, data_len);
+
+ 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);
+#else /* !__GNU__ */
+ struct stat st;
if (stat (dir, &st) < 0)
grub_util_error ("Cannot stat `%s'", dir);
/* This might be truly slow, but is there any better way? */
os_dev = find_root_device ("/dev", st.st_dev);
#endif
+#endif /* !__GNU__ */
return os_dev;
}