/* --- per-PID directory --- */
+/* Forward declarations for file_operations tables used in dynamic node creation */
+static const struct file_operations procfs_pid_dir_fops;
+static const struct file_operations procfs_pid_status_fops;
+static const struct file_operations procfs_pid_maps_fops;
+
static fs_node_t* proc_pid_finddir(fs_node_t* node, const char* name) {
uint32_t pid = node->inode;
uint32_t slot = g_pid_pool_idx;
strcpy(g_pid_status[slot].name, "status");
g_pid_status[slot].flags = FS_FILE;
g_pid_status[slot].inode = pid;
+ g_pid_status[slot].f_ops = &procfs_pid_status_fops;
g_pid_status[slot].read = proc_pid_status_read;
return &g_pid_status[slot];
}
strcpy(g_pid_maps[slot].name, "maps");
g_pid_maps[slot].flags = FS_FILE;
g_pid_maps[slot].inode = pid;
+ g_pid_maps[slot].f_ops = &procfs_pid_maps_fops;
g_pid_maps[slot].read = proc_pid_maps_read;
return &g_pid_maps[slot];
}
strcpy(g_pid_dir[slot].name, num);
g_pid_dir[slot].flags = FS_DIRECTORY;
g_pid_dir[slot].inode = pid;
+ g_pid_dir[slot].f_ops = &procfs_pid_dir_fops;
g_pid_dir[slot].finddir = proc_pid_finddir;
g_pid_dir[slot].readdir = proc_pid_readdir;
return &g_pid_dir[slot];
return 0;
}
+/* --- file_operations tables --- */
+
+static const struct file_operations procfs_root_fops = {
+ .finddir = proc_root_finddir,
+ .readdir = proc_root_readdir,
+};
+
+static const struct file_operations procfs_self_fops = {
+ .finddir = proc_self_finddir,
+ .readdir = proc_self_readdir,
+};
+
+static const struct file_operations procfs_self_status_fops = {
+ .read = proc_self_status_read,
+};
+
+static const struct file_operations procfs_uptime_fops = {
+ .read = proc_uptime_read,
+};
+
+static const struct file_operations procfs_meminfo_fops = {
+ .read = proc_meminfo_read,
+};
+
+static const struct file_operations procfs_cmdline_fops = {
+ .read = proc_cmdline_read,
+};
+
+static const struct file_operations procfs_pid_dir_fops = {
+ .finddir = proc_pid_finddir,
+ .readdir = proc_pid_readdir,
+};
+
+static const struct file_operations procfs_pid_status_fops = {
+ .read = proc_pid_status_read,
+};
+
+static const struct file_operations procfs_pid_maps_fops = {
+ .read = proc_pid_maps_read,
+};
+
fs_node_t* procfs_create_root(void) {
memset(&g_proc_root, 0, sizeof(g_proc_root));
strcpy(g_proc_root.name, "proc");
g_proc_root.flags = FS_DIRECTORY;
+ g_proc_root.f_ops = &procfs_root_fops;
g_proc_root.finddir = proc_root_finddir;
g_proc_root.readdir = proc_root_readdir;
memset(&g_proc_self, 0, sizeof(g_proc_self));
strcpy(g_proc_self.name, "self");
g_proc_self.flags = FS_DIRECTORY;
+ g_proc_self.f_ops = &procfs_self_fops;
g_proc_self.finddir = proc_self_finddir;
g_proc_self.readdir = proc_self_readdir;
memset(&g_proc_self_status, 0, sizeof(g_proc_self_status));
strcpy(g_proc_self_status.name, "status");
g_proc_self_status.flags = FS_FILE;
+ g_proc_self_status.f_ops = &procfs_self_status_fops;
g_proc_self_status.read = proc_self_status_read;
memset(&g_proc_uptime, 0, sizeof(g_proc_uptime));
strcpy(g_proc_uptime.name, "uptime");
g_proc_uptime.flags = FS_FILE;
+ g_proc_uptime.f_ops = &procfs_uptime_fops;
g_proc_uptime.read = proc_uptime_read;
memset(&g_proc_meminfo, 0, sizeof(g_proc_meminfo));
strcpy(g_proc_meminfo.name, "meminfo");
g_proc_meminfo.flags = FS_FILE;
+ g_proc_meminfo.f_ops = &procfs_meminfo_fops;
g_proc_meminfo.read = proc_meminfo_read;
memset(&g_proc_cmdline, 0, sizeof(g_proc_cmdline));
strcpy(g_proc_cmdline.name, "cmdline");
g_proc_cmdline.flags = FS_FILE;
+ g_proc_cmdline.f_ops = &procfs_cmdline_fops;
g_proc_cmdline.read = proc_cmdline_read;
return &g_proc_root;
return revents;
}
+/* Forward declarations for file_operations tables */
+static uint32_t pty_ptmx_read_fn(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer);
+static uint32_t pty_ptmx_write_fn(fs_node_t* node, uint32_t offset, uint32_t size, const uint8_t* buffer);
+static struct fs_node* pty_pts_finddir(struct fs_node* node, const char* name);
+static int pty_pts_readdir(struct fs_node* node, uint32_t* inout_index, void* buf, uint32_t buf_len);
+
+static const struct file_operations pty_master_fops = {
+ .read = pty_master_read_fn,
+ .write = pty_master_write_fn,
+ .poll = pty_master_poll_fn,
+};
+
+static const struct file_operations pty_slave_fops = {
+ .read = pty_slave_read_fn,
+ .write = pty_slave_write_fn,
+ .ioctl = pty_slave_ioctl_fn,
+ .poll = pty_slave_poll_fn,
+};
+
+static const struct file_operations pty_ptmx_fops = {
+ .read = pty_ptmx_read_fn,
+ .write = pty_ptmx_write_fn,
+ .poll = pty_master_poll_fn,
+};
+
+static const struct file_operations pty_pts_dir_fops = {
+ .finddir = pty_pts_finddir,
+ .readdir = pty_pts_readdir,
+};
+
static void pty_init_pair(int idx) {
struct pty_pair* p = &g_ptys[idx];
memset(p, 0, sizeof(*p));
strcpy(p->master_node.name, "ptmx");
p->master_node.flags = FS_CHARDEVICE;
p->master_node.inode = PTY_MASTER_INO_BASE + (uint32_t)idx;
+ p->master_node.f_ops = &pty_master_fops;
p->master_node.read = &pty_master_read_fn;
p->master_node.write = &pty_master_write_fn;
p->master_node.poll = &pty_master_poll_fn;
strcpy(p->slave_node.name, name);
p->slave_node.flags = FS_CHARDEVICE;
p->slave_node.inode = PTY_SLAVE_INO_BASE + (uint32_t)idx;
+ p->slave_node.f_ops = &pty_slave_fops;
p->slave_node.read = &pty_slave_read_fn;
p->slave_node.write = &pty_slave_write_fn;
p->slave_node.ioctl = &pty_slave_ioctl_fn;
strcpy(g_dev_ptmx_node.name, "ptmx");
g_dev_ptmx_node.flags = FS_CHARDEVICE;
g_dev_ptmx_node.inode = PTY_MASTER_INO_BASE;
+ g_dev_ptmx_node.f_ops = &pty_ptmx_fops;
g_dev_ptmx_node.read = &pty_ptmx_read_fn;
g_dev_ptmx_node.write = &pty_ptmx_write_fn;
g_dev_ptmx_node.poll = &pty_master_poll_fn;
strcpy(g_dev_pts_dir_node.name, "pts");
g_dev_pts_dir_node.flags = FS_DIRECTORY;
g_dev_pts_dir_node.inode = 5;
+ g_dev_pts_dir_node.f_ops = &pty_pts_dir_fops;
g_dev_pts_dir_node.finddir = &pty_pts_finddir;
g_dev_pts_dir_node.readdir = &pty_pts_readdir;
devfs_register_device(&g_dev_pts_dir_node);