Switch procfs to use archelp.
This fixes handling of "." and "..".
This commit is contained in:
parent
a2721778e5
commit
4622f4e1ee
2 changed files with 58 additions and 28 deletions
|
@ -48,6 +48,7 @@ library = {
|
||||||
common = grub-core/partmap/gpt.c;
|
common = grub-core/partmap/gpt.c;
|
||||||
common = grub-core/partmap/msdos.c;
|
common = grub-core/partmap/msdos.c;
|
||||||
common = grub-core/fs/proc.c;
|
common = grub-core/fs/proc.c;
|
||||||
|
common = grub-core/fs/archelp.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
library = {
|
library = {
|
||||||
|
@ -91,7 +92,6 @@ library = {
|
||||||
common = grub-core/fs/bfs.c;
|
common = grub-core/fs/bfs.c;
|
||||||
common = grub-core/fs/btrfs.c;
|
common = grub-core/fs/btrfs.c;
|
||||||
common = grub-core/fs/cbfs.c;
|
common = grub-core/fs/cbfs.c;
|
||||||
common = grub-core/fs/archelp.c;
|
|
||||||
common = grub-core/fs/cpio.c;
|
common = grub-core/fs/cpio.c;
|
||||||
common = grub-core/fs/cpio_be.c;
|
common = grub-core/fs/cpio_be.c;
|
||||||
common = grub-core/fs/odc.c;
|
common = grub-core/fs/odc.c;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
|
#include <grub/archelp.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -74,6 +75,44 @@ grub_procdev_write (grub_disk_t disk __attribute ((unused)),
|
||||||
return GRUB_ERR_OUT_OF_RANGE;
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct grub_archelp_data
|
||||||
|
{
|
||||||
|
struct grub_procfs_entry *entry, *next_entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_procfs_rewind (struct grub_archelp_data *data)
|
||||||
|
{
|
||||||
|
data->entry = NULL;
|
||||||
|
data->next_entry = grub_procfs_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_procfs_find_file (struct grub_archelp_data *data, char **name,
|
||||||
|
grub_int32_t *mtime,
|
||||||
|
grub_uint32_t *mode)
|
||||||
|
{
|
||||||
|
data->entry = data->next_entry;
|
||||||
|
if (!data->entry)
|
||||||
|
{
|
||||||
|
*mode = GRUB_ARCHELP_ATTR_END;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
data->next_entry = data->entry->next;
|
||||||
|
*mode = GRUB_ARCHELP_ATTR_FILE | GRUB_ARCHELP_ATTR_NOTIME;
|
||||||
|
*name = grub_strdup (data->entry->name);
|
||||||
|
*mtime = 0;
|
||||||
|
if (!*name)
|
||||||
|
return grub_errno;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_archelp_ops arcops =
|
||||||
|
{
|
||||||
|
.find_file = grub_procfs_find_file,
|
||||||
|
.rewind = grub_procfs_rewind
|
||||||
|
};
|
||||||
|
|
||||||
static grub_ssize_t
|
static grub_ssize_t
|
||||||
grub_procfs_read (grub_file_t file, char *buf, grub_size_t len)
|
grub_procfs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
{
|
{
|
||||||
|
@ -99,44 +138,35 @@ static grub_err_t
|
||||||
grub_procfs_dir (grub_device_t device, const char *path,
|
grub_procfs_dir (grub_device_t device, const char *path,
|
||||||
grub_fs_dir_hook_t hook, void *hook_data)
|
grub_fs_dir_hook_t hook, void *hook_data)
|
||||||
{
|
{
|
||||||
const char *ptr;
|
struct grub_archelp_data data;
|
||||||
struct grub_dirhook_info info;
|
|
||||||
struct grub_procfs_entry *entry;
|
|
||||||
|
|
||||||
grub_memset (&info, 0, sizeof (info));
|
|
||||||
|
|
||||||
/* Check if the disk is our dummy disk. */
|
/* Check if the disk is our dummy disk. */
|
||||||
if (grub_strcmp (device->disk->name, "proc"))
|
if (grub_strcmp (device->disk->name, "proc"))
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "not a procfs");
|
return grub_error (GRUB_ERR_BAD_FS, "not a procfs");
|
||||||
for (ptr = path; *ptr == '/'; ptr++);
|
|
||||||
if (*ptr)
|
grub_procfs_rewind (&data);
|
||||||
return 0;
|
|
||||||
FOR_LIST_ELEMENTS((entry), (grub_procfs_entries))
|
return grub_archelp_dir (&data, &arcops,
|
||||||
if (hook (entry->name, &info, hook_data))
|
path, hook, hook_data);
|
||||||
return 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_procfs_open (struct grub_file *file, const char *path)
|
grub_procfs_open (struct grub_file *file, const char *path)
|
||||||
{
|
{
|
||||||
const char *pathptr;
|
grub_err_t err;
|
||||||
struct grub_procfs_entry *entry;
|
struct grub_archelp_data data;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
for (pathptr = path; *pathptr == '/'; pathptr++);
|
grub_procfs_rewind (&data);
|
||||||
|
|
||||||
FOR_LIST_ELEMENTS((entry), (grub_procfs_entries))
|
err = grub_archelp_open (&data, &arcops, path);
|
||||||
if (grub_strcmp (pathptr, entry->name) == 0)
|
if (err)
|
||||||
{
|
return err;
|
||||||
grub_size_t sz;
|
file->data = data.entry->get_contents (&sz);
|
||||||
file->data = entry->get_contents (&sz);
|
if (!file->data)
|
||||||
if (!file->data)
|
return grub_errno;
|
||||||
return grub_errno;
|
file->size = sz;
|
||||||
file->size = sz;
|
return GRUB_ERR_NONE;
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct grub_disk_dev grub_procfs_dev = {
|
static struct grub_disk_dev grub_procfs_dev = {
|
||||||
|
|
Loading…
Reference in a new issue