123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864 |
- /* vim: tabstop=4 shiftwidth=4 noexpandtab
- * This file is part of ToaruOS and is released under the terms
- * of the NCSA / University of Illinois License - see LICENSE.md
- * Copyright (C) 2014-2018 K. Lange
- */
- #include <kernel/system.h>
- #include <kernel/logging.h>
- #include <kernel/fs.h>
- #include <kernel/version.h>
- #include <kernel/process.h>
- #include <kernel/printf.h>
- #include <kernel/module.h>
- #include <kernel/multiboot.h>
- #include <kernel/pci.h>
- #include <kernel/mod/procfs.h>
- #define PROCFS_STANDARD_ENTRIES (sizeof(std_entries) / sizeof(struct procfs_entry))
- #define PROCFS_PROCDIR_ENTRIES (sizeof(procdir_entries) / sizeof(struct procfs_entry))
- static fs_node_t * procfs_generic_create(char * name, read_type_t read_func) {
- fs_node_t * fnode = malloc(sizeof(fs_node_t));
- memset(fnode, 0x00, sizeof(fs_node_t));
- fnode->inode = 0;
- strcpy(fnode->name, name);
- fnode->uid = 0;
- fnode->gid = 0;
- fnode->mask = 0444;
- fnode->flags = FS_FILE;
- fnode->read = read_func;
- fnode->write = NULL;
- fnode->open = NULL;
- fnode->close = NULL;
- fnode->readdir = NULL;
- fnode->finddir = NULL;
- fnode->ctime = now();
- fnode->mtime = now();
- fnode->atime = now();
- return fnode;
- }
- static uint32_t proc_cmdline_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char buf[1024];
- process_t * proc = process_from_pid(node->inode);
- if (!proc) {
- /* wat */
- return 0;
- }
- if (!proc->cmdline) {
- sprintf(buf, "%s", proc->name);
- size_t _bsize = strlen(buf);
- if (offset > _bsize) return 0;
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- return size;
- }
- buf[0] = '\0';
- char * _buf = buf;
- char ** args = proc->cmdline;
- while (*args) {
- strcpy(_buf, *args);
- _buf += strlen(_buf);
- if (*(args+1)) {
- strcpy(_buf, "\036");
- _buf += strlen(_buf);
- }
- args++;
- }
- size_t _bsize = strlen(buf);
- if (offset > _bsize) return 0;
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- return size;
- }
- static size_t calculate_memory_usage(page_directory_t * src) {
- size_t pages = 0;
- for (uint32_t i = 0; i < 1024; ++i) {
- if (!src->tables[i] || (uintptr_t)src->tables[i] == (uintptr_t)0xFFFFFFFF) {
- continue;
- }
- if (kernel_directory->tables[i] == src->tables[i]) {
- continue;
- }
- /* For each table */
- if (i * 0x1000 * 1024 < SHM_START) {
- /* Ignore shared memory for now */
- for (int j = 0; j < 1024; ++j) {
- /* For each frame in the table... */
- if (!src->tables[i]->pages[j].frame) {
- continue;
- }
- pages++;
- }
- }
- }
- return pages;
- }
- static size_t calculate_shm_resident(page_directory_t * src) {
- size_t pages = 0;
- for (uint32_t i = 0; i < 1024; ++i) {
- if (!src->tables[i] || (uintptr_t)src->tables[i] == (uintptr_t)0xFFFFFFFF) {
- continue;
- }
- if (kernel_directory->tables[i] == src->tables[i]) {
- continue;
- }
- if (i * 0x1000 * 1024 < SHM_START) {
- continue;
- }
- for (int j = 0; j < 1024; ++j) {
- /* For each frame in the table... */
- if (!src->tables[i]->pages[j].frame) {
- continue;
- }
- pages++;
- }
- }
- return pages;
- }
- static uint32_t proc_status_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char buf[2048];
- process_t * proc = process_from_pid(node->inode);
- process_t * parent = process_get_parent(proc);
- if (!proc) {
- /* wat */
- return 0;
- }
- char state = proc->finished ? 'Z' : (process_is_ready(proc) ? 'R' : 'S');
- char * name = proc->name + strlen(proc->name) - 1;
- while (1) {
- if (*name == '/') {
- name++;
- break;
- }
- if (name == proc->name) break;
- name--;
- }
- /* Calculate process memory usage */
- int mem_usage = calculate_memory_usage(proc->thread.page_directory) * 4;
- int shm_usage = calculate_shm_resident(proc->thread.page_directory) * 4;
- int mem_permille = 1000 * (mem_usage + shm_usage) / memory_total();
- sprintf(buf,
- "Name:\t%s\n" /* name */
- "State:\t%c\n" /* yeah, do this at some point */
- "Tgid:\t%d\n" /* group ? group : pid */
- "Pid:\t%d\n" /* pid */
- "PPid:\t%d\n" /* parent pid */
- "Uid:\t%d\n"
- "Ueip:\t0x%x\n"
- "SCid:\t%d\n"
- "SC0:\t0x%x\n"
- "SC1:\t0x%x\n"
- "SC2:\t0x%x\n"
- "SC3:\t0x%x\n"
- "SC4:\t0x%x\n"
- "UserStack:\t0x%x\n"
- "Path:\t%s\n"
- "VmSize:\t %d kB\n"
- "RssShmem:\t %d kB\n"
- "MemPermille:\t %d\n"
- ,
- name,
- state,
- proc->group ? proc->group : proc->id,
- proc->id,
- parent ? parent->id : 0,
- proc->user,
- proc->syscall_registers ? proc->syscall_registers->eip : 0,
- proc->syscall_registers ? proc->syscall_registers->eax : 0,
- proc->syscall_registers ? proc->syscall_registers->ebx : 0,
- proc->syscall_registers ? proc->syscall_registers->ecx : 0,
- proc->syscall_registers ? proc->syscall_registers->edx : 0,
- proc->syscall_registers ? proc->syscall_registers->esi : 0,
- proc->syscall_registers ? proc->syscall_registers->edi : 0,
- proc->syscall_registers ? proc->syscall_registers->useresp : 0,
- proc->cmdline ? proc->cmdline[0] : "(none)",
- mem_usage, shm_usage, mem_permille
- );
- size_t _bsize = strlen(buf);
- if (offset > _bsize) return 0;
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- return size;
- }
- static struct procfs_entry procdir_entries[] = {
- {1, "cmdline", proc_cmdline_func},
- {2, "status", proc_status_func},
- };
- static struct dirent * readdir_procfs_procdir(fs_node_t *node, uint32_t index) {
- if (index == 0) {
- struct dirent * out = malloc(sizeof(struct dirent));
- memset(out, 0x00, sizeof(struct dirent));
- out->ino = 0;
- strcpy(out->name, ".");
- return out;
- }
- if (index == 1) {
- struct dirent * out = malloc(sizeof(struct dirent));
- memset(out, 0x00, sizeof(struct dirent));
- out->ino = 0;
- strcpy(out->name, "..");
- return out;
- }
- index -= 2;
- if (index < PROCFS_PROCDIR_ENTRIES) {
- struct dirent * out = malloc(sizeof(struct dirent));
- memset(out, 0x00, sizeof(struct dirent));
- out->ino = procdir_entries[index].id;
- strcpy(out->name, procdir_entries[index].name);
- return out;
- }
- return NULL;
- }
- static fs_node_t * finddir_procfs_procdir(fs_node_t * node, char * name) {
- if (!name) return NULL;
- for (unsigned int i = 0; i < PROCFS_PROCDIR_ENTRIES; ++i) {
- if (!strcmp(name, procdir_entries[i].name)) {
- fs_node_t * out = procfs_generic_create(procdir_entries[i].name, procdir_entries[i].func);
- out->inode = node->inode;
- return out;
- }
- }
- return NULL;
- }
- static fs_node_t * procfs_procdir_create(process_t * process) {
- pid_t pid = process->id;
- fs_node_t * fnode = malloc(sizeof(fs_node_t));
- memset(fnode, 0x00, sizeof(fs_node_t));
- fnode->inode = pid;
- sprintf(fnode->name, "%d", pid);
- fnode->uid = 0;
- fnode->gid = 0;
- fnode->mask = 0555;
- fnode->flags = FS_DIRECTORY;
- fnode->read = NULL;
- fnode->write = NULL;
- fnode->open = NULL;
- fnode->close = NULL;
- fnode->readdir = readdir_procfs_procdir;
- fnode->finddir = finddir_procfs_procdir;
- fnode->nlink = 1;
- fnode->ctime = process->start.tv_sec;
- fnode->mtime = process->start.tv_sec;
- fnode->atime = process->start.tv_sec;
- return fnode;
- }
- #define cpuid(in,a,b,c,d) do { asm volatile ("cpuid" : "=a"(a),"=b"(b),"=c"(c),"=d"(d) : "a"(in)); } while(0)
- static uint32_t cpuinfo_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char buf[1024];
- unsigned long a, b, unused;;
- cpuid(0,unused,b,unused,unused);
- char * _manu = "Unknown";
- int _model = 0, _family = 0;
- if (b == 0x756e6547) {
- cpuid(1, a, b, unused, unused);
- _manu = "Intel";
- _model = (a >> 4) & 0x0F;
- _family = (a >> 8) & 0x0F;
- } else if (b == 0x68747541) {
- cpuid(1, a, unused, unused, unused);
- _manu = "AMD";
- _model = (a >> 4) & 0x0F;
- _family = (a >> 8) & 0x0F;
- }
- sprintf(buf,
- "Manufacturer: %s\n"
- "Family: %d\n"
- "Model: %d\n"
- , _manu, _family, _model);
- size_t _bsize = strlen(buf);
- if (offset > _bsize) return 0;
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- return size;
- }
- extern uintptr_t heap_end;
- extern uintptr_t kernel_heap_alloc_point;
- static uint32_t meminfo_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char buf[1024];
- unsigned int total = memory_total();
- unsigned int free = total - memory_use();
- unsigned int kheap = (heap_end - kernel_heap_alloc_point) / 1024;
- sprintf(buf,
- "MemTotal: %d kB\n"
- "MemFree: %d kB\n"
- "KHeapUse: %d kB\n"
- , total, free, kheap);
- size_t _bsize = strlen(buf);
- if (offset > _bsize) return 0;
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- return size;
- }
- static uint32_t pat_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char buf[1024];
- uint64_t pat_values;
- asm volatile ( "rdmsr" : "=A" (pat_values) : "c" (0x277) );
- char * pat_names[] = {
- "uncacheable (UC)",
- "write combining (WC)",
- "Reserved",
- "Reserved",
- "write through (WT)",
- "write protected (WP)",
- "write back (WB)",
- "uncached (UC-)"
- };
- int pa_0 = (pat_values >> 0) & 0x7;
- int pa_1 = (pat_values >> 8) & 0x7;
- int pa_2 = (pat_values >> 16) & 0x7;
- int pa_3 = (pat_values >> 24) & 0x7;
- int pa_4 = (pat_values >> 32) & 0x7;
- int pa_5 = (pat_values >> 40) & 0x7;
- int pa_6 = (pat_values >> 48) & 0x7;
- int pa_7 = (pat_values >> 56) & 0x7;
- sprintf(buf,
- "PA0: %d %s\n"
- "PA1: %d %s\n"
- "PA2: %d %s\n"
- "PA3: %d %s\n"
- "PA4: %d %s\n"
- "PA5: %d %s\n"
- "PA6: %d %s\n"
- "PA7: %d %s\n",
- pa_0, pat_names[pa_0],
- pa_1, pat_names[pa_1],
- pa_2, pat_names[pa_2],
- pa_3, pat_names[pa_3],
- pa_4, pat_names[pa_4],
- pa_5, pat_names[pa_5],
- pa_6, pat_names[pa_6],
- pa_7, pat_names[pa_7]
- );
- size_t _bsize = strlen(buf);
- if (offset > _bsize) return 0;
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- return size;
- }
- static uint32_t uptime_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char buf[1024];
- sprintf(buf, "%d.%3d\n", timer_ticks, timer_subticks);
- size_t _bsize = strlen(buf);
- if (offset > _bsize) return 0;
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- return size;
- }
- static uint32_t cmdline_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char buf[1024];
- extern char * cmdline;
- sprintf(buf, "%s\n", cmdline ? cmdline : "");
- size_t _bsize = strlen(buf);
- if (offset > _bsize) return 0;
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- return size;
- }
- static uint32_t version_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char buf[1024];
- char version_number[512];
- sprintf(version_number, __kernel_version_format,
- __kernel_version_major,
- __kernel_version_minor,
- __kernel_version_lower,
- __kernel_version_suffix);
- sprintf(buf, "%s %s %s %s %s %s\n",
- __kernel_name,
- version_number,
- __kernel_version_codename,
- __kernel_build_date,
- __kernel_build_time,
- __kernel_arch);
- size_t _bsize = strlen(buf);
- if (offset > _bsize) return 0;
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- return size;
- }
- static uint32_t compiler_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char buf[1024];
- sprintf(buf, "%s\n", __kernel_compiler_version);
- size_t _bsize = strlen(buf);
- if (offset > _bsize) return 0;
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- return size;
- }
- extern tree_t * fs_tree; /* kernel/fs/vfs.c */
- static void mount_recurse(char * buf, tree_node_t * node, size_t height) {
- /* End recursion on a blank entry */
- if (!node) return;
- char * tmp = malloc(512);
- memset(tmp, 0, 512);
- char * c = tmp;
- /* Indent output */
- for (uint32_t i = 0; i < height; ++i) {
- c += sprintf(c, " ");
- }
- /* Get the current process */
- struct vfs_entry * fnode = (struct vfs_entry *)node->value;
- /* Print the process name */
- if (fnode->file) {
- c += sprintf(c, "%s → %s 0x%x (%s, %s)", fnode->name, fnode->device, fnode->file, fnode->fs_type, fnode->file->name);
- } else {
- c += sprintf(c, "%s → (empty)", fnode->name);
- }
- /* Linefeed */
- sprintf(buf+strlen(buf),"%s\n",tmp);
- free(tmp);
- foreach(child, node->children) {
- /* Recursively print the children */
- mount_recurse(buf+strlen(buf),child->value, height + 1);
- }
- }
- static uint32_t mounts_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char * buf = malloc(4096);
- buf[0] = '\0';
- mount_recurse(buf, fs_tree->root, 0);
- size_t _bsize = strlen(buf);
- if (offset > _bsize) {
- free(buf);
- return 0;
- }
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- free(buf);
- return size;
- }
- static uint32_t modules_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- list_t * hash_keys = hashmap_keys(modules_get_list());
- char * buf = malloc(hash_keys->length * 512);
- unsigned int soffset = 0;
- foreach(_key, hash_keys) {
- char * key = (char *)_key->value;
- module_data_t * mod_info = hashmap_get(modules_get_list(), key);
- soffset += sprintf(&buf[soffset], "0x%x {.init=0x%x, .fini=0x%x} %s",
- mod_info->bin_data,
- mod_info->mod_info->initialize,
- mod_info->mod_info->finalize,
- mod_info->mod_info->name);
- if (mod_info->deps) {
- unsigned int i = 0;
- soffset += sprintf(&buf[soffset], " Deps: ");
- while (i < mod_info->deps_length) {
- /* Skip padding bytes */
- if (strlen(&mod_info->deps[i])) {
- soffset += sprintf(&buf[soffset], "%s ", &mod_info->deps[i]);
- }
- i += strlen(&mod_info->deps[i]) + 1;
- }
- }
- soffset += sprintf(&buf[soffset], "\n");
- }
- free(hash_keys);
- size_t _bsize = strlen(buf);
- if (offset > _bsize) {
- free(buf);
- return 0;
- }
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- free(buf);
- return size;
- }
- extern hashmap_t * fs_types; /* from kernel/fs/vfs.c */
- static uint32_t filesystems_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- list_t * hash_keys = hashmap_keys(fs_types);
- char * buf = malloc(hash_keys->length * 512);
- unsigned int soffset = 0;
- foreach(_key, hash_keys) {
- char * key = (char *)_key->value;
- soffset += sprintf(&buf[soffset], "%s\n", key);
- }
- free(hash_keys);
- size_t _bsize = strlen(buf);
- if (offset > _bsize) {
- free(buf);
- return 0;
- }
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- free(buf);
- return size;
- }
- static uint32_t loader_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char * buf = malloc(512);
- if (mboot_ptr->flags & MULTIBOOT_FLAG_LOADER) {
- sprintf(buf, "%s\n", mboot_ptr->boot_loader_name);
- } else {
- buf[0] = '\n';
- buf[1] = '\0';
- }
- size_t _bsize = strlen(buf);
- if (offset > _bsize) {
- free(buf);
- return 0;
- }
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- free(buf);
- return size;
- }
- extern char * get_irq_handler(int irq, int chain);
- static uint32_t irq_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- char * buf = malloc(4096);
- unsigned int soffset = 0;
- for (int i = 0; i < 16; ++i) {
- soffset += sprintf(&buf[soffset], "irq %d: ", i);
- for (int j = 0; j < 4; ++j) {
- char * t = get_irq_handler(i, j);
- if (!t) break;
- soffset += sprintf(&buf[soffset], "%s%s", j ? "," : "", t);
- }
- soffset += sprintf(&buf[soffset], "\n");
- }
- size_t _bsize = strlen(buf);
- if (offset > _bsize) {
- free(buf);
- return 0;
- }
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, buf + offset, size);
- free(buf);
- return size;
- }
- /**
- * Basically the same as the kdebug `pci` command.
- */
- struct _pci_buf {
- size_t offset;
- char *buffer;
- };
- static void scan_hit_list(uint32_t device, uint16_t vendorid, uint16_t deviceid, void * extra) {
- struct _pci_buf * b = extra;
- b->offset += sprintf(b->buffer + b->offset, "%2x:%2x.%d (%4x, %4x:%4x) %s %s\n",
- (int)pci_extract_bus(device),
- (int)pci_extract_slot(device),
- (int)pci_extract_func(device),
- (int)pci_find_type(device),
- vendorid,
- deviceid,
- pci_vendor_lookup(vendorid),
- pci_device_lookup(vendorid,deviceid));
- b->offset += sprintf(b->buffer + b->offset, " BAR0: 0x%8x", pci_read_field(device, PCI_BAR0, 4));
- b->offset += sprintf(b->buffer + b->offset, " BAR1: 0x%8x", pci_read_field(device, PCI_BAR1, 4));
- b->offset += sprintf(b->buffer + b->offset, " BAR2: 0x%8x", pci_read_field(device, PCI_BAR2, 4));
- b->offset += sprintf(b->buffer + b->offset, " BAR3: 0x%8x", pci_read_field(device, PCI_BAR3, 4));
- b->offset += sprintf(b->buffer + b->offset, " BAR4: 0x%8x", pci_read_field(device, PCI_BAR4, 4));
- b->offset += sprintf(b->buffer + b->offset, " BAR6: 0x%8x\n", pci_read_field(device, PCI_BAR5, 4));
- b->offset += sprintf(b->buffer + b->offset, " IRQ Line: %d", pci_read_field(device, 0x3C, 1));
- b->offset += sprintf(b->buffer + b->offset, " IRQ Pin: %d", pci_read_field(device, 0x3D, 1));
- b->offset += sprintf(b->buffer + b->offset, " Interrupt: %d", pci_get_interrupt(device));
- b->offset += sprintf(b->buffer + b->offset, " Status: 0x%4x\n", pci_read_field(device, PCI_STATUS, 2));
- }
- static void scan_count(uint32_t device, uint16_t vendorid, uint16_t deviceid, void * extra) {
- size_t * count = extra;
- (*count)++;
- }
- static uint32_t pci_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
- size_t count = 0;
- pci_scan(&scan_count, -1, &count);
- struct _pci_buf b = {0,NULL};
- b.buffer = malloc(count * 1024);
- pci_scan(&scan_hit_list, -1, &b);
- size_t _bsize = b.offset;
- if (offset > _bsize) {
- free(b.buffer);
- return 0;
- }
- if (size > _bsize - offset) size = _bsize - offset;
- memcpy(buffer, b.buffer + offset, size);
- free(b.buffer);
- return size;
- }
- static struct procfs_entry std_entries[] = {
- {-1, "cpuinfo", cpuinfo_func},
- {-2, "meminfo", meminfo_func},
- {-3, "uptime", uptime_func},
- {-4, "cmdline", cmdline_func},
- {-5, "version", version_func},
- {-6, "compiler", compiler_func},
- {-7, "mounts", mounts_func},
- {-8, "modules", modules_func},
- {-9, "filesystems", filesystems_func},
- {-10,"loader", loader_func},
- {-11,"irq", irq_func},
- {-12,"pat", pat_func},
- {-13,"pci", pci_func},
- };
- static list_t * extended_entries = NULL;
- static int next_id = 0;
- int procfs_install(struct procfs_entry * entry) {
- if (!extended_entries) {
- extended_entries = list_create();
- next_id = -PROCFS_STANDARD_ENTRIES - 1;
- }
- entry->id = next_id--;
- list_insert(extended_entries, entry);
- return 0;
- }
- static struct dirent * readdir_procfs_root(fs_node_t *node, uint32_t index) {
- if (index == 0) {
- struct dirent * out = malloc(sizeof(struct dirent));
- memset(out, 0x00, sizeof(struct dirent));
- out->ino = 0;
- strcpy(out->name, ".");
- return out;
- }
- if (index == 1) {
- struct dirent * out = malloc(sizeof(struct dirent));
- memset(out, 0x00, sizeof(struct dirent));
- out->ino = 0;
- strcpy(out->name, "..");
- return out;
- }
- if (index == 2) {
- struct dirent * out = malloc(sizeof(struct dirent));
- memset(out, 0x00, sizeof(struct dirent));
- out->ino = 0;
- strcpy(out->name, "self");
- return out;
- }
- index -= 3;
- if (index < PROCFS_STANDARD_ENTRIES) {
- struct dirent * out = malloc(sizeof(struct dirent));
- memset(out, 0x00, sizeof(struct dirent));
- out->ino = std_entries[index].id;
- strcpy(out->name, std_entries[index].name);
- return out;
- }
- index -= PROCFS_STANDARD_ENTRIES;
- if (extended_entries) {
- if (index < extended_entries->length) {
- size_t i = 0;
- node_t * n = extended_entries->head;
- while (i < index) {
- n = n->next;
- i++;
- }
- struct procfs_entry * e = n->value;
- struct dirent * out = malloc(sizeof(struct dirent));
- memset(out, 0x00, sizeof(struct dirent));
- out->ino = e->id;
- strcpy(out->name, e->name);
- return out;
- }
- index -= extended_entries->length;
- }
- int i = index + 1;
- debug_print(WARNING, "%d %d %d", i, index, PROCFS_STANDARD_ENTRIES);
- pid_t pid = 0;
- foreach(lnode, process_list) {
- i--;
- if (i == 0) {
- process_t * proc = (process_t *)lnode->value;
- pid = proc->id;
- break;
- }
- }
- if (pid == 0) {
- return NULL;
- }
- struct dirent * out = malloc(sizeof(struct dirent));
- memset(out, 0x00, sizeof(struct dirent));
- out->ino = pid;
- sprintf(out->name, "%d", pid);
- return out;
- }
- static fs_node_t * finddir_procfs_root(fs_node_t * node, char * name) {
- if (!name) return NULL;
- if (strlen(name) < 1) return NULL;
- if (name[0] >= '0' && name[0] <= '9') {
- /* XXX process entries */
- pid_t pid = atoi(name);
- process_t * proc = process_from_pid(pid);
- if (!proc) {
- return NULL;
- }
- fs_node_t * out = procfs_procdir_create(proc);
- return out;
- }
- if (!strcmp(name,"self")) {
- return procfs_procdir_create((process_t *)current_process);
- }
- for (unsigned int i = 0; i < PROCFS_STANDARD_ENTRIES; ++i) {
- if (!strcmp(name, std_entries[i].name)) {
- fs_node_t * out = procfs_generic_create(std_entries[i].name, std_entries[i].func);
- return out;
- }
- }
- foreach(node, extended_entries) {
- struct procfs_entry * e = node->value;
- if (!strcmp(name, e->name)) {
- fs_node_t * out = procfs_generic_create(e->name, e->func);
- return out;
- }
- }
- return NULL;
- }
- static fs_node_t * procfs_create(void) {
- fs_node_t * fnode = malloc(sizeof(fs_node_t));
- memset(fnode, 0x00, sizeof(fs_node_t));
- fnode->inode = 0;
- strcpy(fnode->name, "proc");
- fnode->mask = 0555;
- fnode->uid = 0;
- fnode->gid = 0;
- fnode->flags = FS_DIRECTORY;
- fnode->read = NULL;
- fnode->write = NULL;
- fnode->open = NULL;
- fnode->close = NULL;
- fnode->readdir = readdir_procfs_root;
- fnode->finddir = finddir_procfs_root;
- fnode->nlink = 1;
- fnode->ctime = now();
- fnode->mtime = now();
- fnode->atime = now();
- return fnode;
- }
- int procfs_initialize(void) {
- /* TODO Move this to some sort of config */
- vfs_mount("/proc", procfs_create());
- debug_print_vfs_tree();
- return 0;
- }
- int procfs_finalize(void) {
- return 0;
- }
- MODULE_DEF(procfs, procfs_initialize, procfs_finalize);
|