procfs.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2014-2018 K. Lange
  5. */
  6. #include <kernel/system.h>
  7. #include <kernel/logging.h>
  8. #include <kernel/fs.h>
  9. #include <kernel/version.h>
  10. #include <kernel/process.h>
  11. #include <kernel/printf.h>
  12. #include <kernel/module.h>
  13. #include <kernel/mod/net.h>
  14. #include <kernel/multiboot.h>
  15. #define PROCFS_STANDARD_ENTRIES (sizeof(std_entries) / sizeof(struct procfs_entry))
  16. #define PROCFS_PROCDIR_ENTRIES (sizeof(procdir_entries) / sizeof(struct procfs_entry))
  17. struct procfs_entry {
  18. int id;
  19. char * name;
  20. read_type_t func;
  21. };
  22. static fs_node_t * procfs_generic_create(char * name, read_type_t read_func) {
  23. fs_node_t * fnode = malloc(sizeof(fs_node_t));
  24. memset(fnode, 0x00, sizeof(fs_node_t));
  25. fnode->inode = 0;
  26. strcpy(fnode->name, name);
  27. fnode->uid = 0;
  28. fnode->gid = 0;
  29. fnode->mask = 0444;
  30. fnode->flags = FS_FILE;
  31. fnode->read = read_func;
  32. fnode->write = NULL;
  33. fnode->open = NULL;
  34. fnode->close = NULL;
  35. fnode->readdir = NULL;
  36. fnode->finddir = NULL;
  37. fnode->ctime = now();
  38. fnode->mtime = now();
  39. fnode->atime = now();
  40. return fnode;
  41. }
  42. static uint32_t proc_cmdline_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  43. char buf[1024];
  44. process_t * proc = process_from_pid(node->inode);
  45. if (!proc) {
  46. /* wat */
  47. return 0;
  48. }
  49. if (!proc->cmdline) {
  50. sprintf(buf, "%s", proc->name);
  51. size_t _bsize = strlen(buf);
  52. if (offset > _bsize) return 0;
  53. if (size > _bsize - offset) size = _bsize - offset;
  54. memcpy(buffer, buf + offset, size);
  55. return size;
  56. }
  57. buf[0] = '\0';
  58. char * _buf = buf;
  59. char ** args = proc->cmdline;
  60. while (*args) {
  61. strcpy(_buf, *args);
  62. _buf += strlen(_buf);
  63. if (*(args+1)) {
  64. strcpy(_buf, "\036");
  65. _buf += strlen(_buf);
  66. }
  67. args++;
  68. }
  69. size_t _bsize = strlen(buf);
  70. if (offset > _bsize) return 0;
  71. if (size > _bsize - offset) size = _bsize - offset;
  72. memcpy(buffer, buf + offset, size);
  73. return size;
  74. }
  75. static uint32_t proc_status_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  76. char buf[2048];
  77. process_t * proc = process_from_pid(node->inode);
  78. process_t * parent = process_get_parent(proc);
  79. if (!proc) {
  80. /* wat */
  81. return 0;
  82. }
  83. char state = process_is_ready(proc) ? 'R' : 'S';
  84. char * name = proc->name + strlen(proc->name) - 1;
  85. while (1) {
  86. if (*name == '/') {
  87. name++;
  88. break;
  89. }
  90. if (name == proc->name) break;
  91. name--;
  92. }
  93. sprintf(buf,
  94. "Name:\t%s\n" /* name */
  95. "State:\t%c\n" /* yeah, do this at some point */
  96. "Tgid:\t%d\n" /* group ? group : pid */
  97. "Pid:\t%d\n" /* pid */
  98. "PPid:\t%d\n" /* parent pid */
  99. "Uid:\t%d\n"
  100. "Ueip:\t0x%x\n"
  101. "SCid:\t%d\n"
  102. "SC0:\t0x%x\n"
  103. "SC1:\t0x%x\n"
  104. "SC2:\t0x%x\n"
  105. "SC3:\t0x%x\n"
  106. "SC4:\t0x%x\n"
  107. "Path:\t%s\n"
  108. ,
  109. name,
  110. state,
  111. proc->group ? proc->group : proc->id,
  112. proc->id,
  113. parent ? parent->id : 0,
  114. proc->user,
  115. proc->syscall_registers ? proc->syscall_registers->eip : 0,
  116. proc->syscall_registers ? proc->syscall_registers->eax : 0,
  117. proc->syscall_registers ? proc->syscall_registers->ebx : 0,
  118. proc->syscall_registers ? proc->syscall_registers->ecx : 0,
  119. proc->syscall_registers ? proc->syscall_registers->edx : 0,
  120. proc->syscall_registers ? proc->syscall_registers->esi : 0,
  121. proc->syscall_registers ? proc->syscall_registers->edi : 0,
  122. proc->cmdline ? proc->cmdline[0] : "(none)"
  123. );
  124. size_t _bsize = strlen(buf);
  125. if (offset > _bsize) return 0;
  126. if (size > _bsize - offset) size = _bsize - offset;
  127. memcpy(buffer, buf + offset, size);
  128. return size;
  129. }
  130. static struct procfs_entry procdir_entries[] = {
  131. {1, "cmdline", proc_cmdline_func},
  132. {2, "status", proc_status_func},
  133. };
  134. static struct dirent * readdir_procfs_procdir(fs_node_t *node, uint32_t index) {
  135. if (index == 0) {
  136. struct dirent * out = malloc(sizeof(struct dirent));
  137. memset(out, 0x00, sizeof(struct dirent));
  138. out->ino = 0;
  139. strcpy(out->name, ".");
  140. return out;
  141. }
  142. if (index == 1) {
  143. struct dirent * out = malloc(sizeof(struct dirent));
  144. memset(out, 0x00, sizeof(struct dirent));
  145. out->ino = 0;
  146. strcpy(out->name, "..");
  147. return out;
  148. }
  149. index -= 2;
  150. if (index < PROCFS_PROCDIR_ENTRIES) {
  151. struct dirent * out = malloc(sizeof(struct dirent));
  152. memset(out, 0x00, sizeof(struct dirent));
  153. out->ino = procdir_entries[index].id;
  154. strcpy(out->name, procdir_entries[index].name);
  155. return out;
  156. }
  157. return NULL;
  158. }
  159. static fs_node_t * finddir_procfs_procdir(fs_node_t * node, char * name) {
  160. if (!name) return NULL;
  161. for (unsigned int i = 0; i < PROCFS_PROCDIR_ENTRIES; ++i) {
  162. if (!strcmp(name, procdir_entries[i].name)) {
  163. fs_node_t * out = procfs_generic_create(procdir_entries[i].name, procdir_entries[i].func);
  164. out->inode = node->inode;
  165. return out;
  166. }
  167. }
  168. return NULL;
  169. }
  170. static fs_node_t * procfs_procdir_create(process_t * process) {
  171. pid_t pid = process->id;
  172. fs_node_t * fnode = malloc(sizeof(fs_node_t));
  173. memset(fnode, 0x00, sizeof(fs_node_t));
  174. fnode->inode = pid;
  175. sprintf(fnode->name, "%d", pid);
  176. fnode->uid = 0;
  177. fnode->gid = 0;
  178. fnode->mask = 0555;
  179. fnode->flags = FS_DIRECTORY;
  180. fnode->read = NULL;
  181. fnode->write = NULL;
  182. fnode->open = NULL;
  183. fnode->close = NULL;
  184. fnode->readdir = readdir_procfs_procdir;
  185. fnode->finddir = finddir_procfs_procdir;
  186. fnode->nlink = 1;
  187. fnode->ctime = process->start.tv_sec;
  188. fnode->mtime = process->start.tv_sec;
  189. fnode->atime = process->start.tv_sec;
  190. return fnode;
  191. }
  192. #define cpuid(in,a,b,c,d) do { asm volatile ("cpuid" : "=a"(a),"=b"(b),"=c"(c),"=d"(d) : "a"(in)); } while(0)
  193. static uint32_t cpuinfo_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  194. char buf[1024];
  195. unsigned long a, b, unused;;
  196. cpuid(0,unused,b,unused,unused);
  197. char * _manu = "Unknown";
  198. int _model = 0, _family = 0;
  199. if (b == 0x756e6547) {
  200. cpuid(1, a, b, unused, unused);
  201. _manu = "Intel";
  202. _model = (a >> 4) & 0x0F;
  203. _family = (a >> 8) & 0x0F;
  204. } else if (b == 0x68747541) {
  205. cpuid(1, a, unused, unused, unused);
  206. _manu = "AMD";
  207. _model = (a >> 4) & 0x0F;
  208. _family = (a >> 8) & 0x0F;
  209. }
  210. sprintf(buf,
  211. "Manufacturer: %s\n"
  212. "Family: %d\n"
  213. "Model: %d\n"
  214. , _manu, _family, _model);
  215. size_t _bsize = strlen(buf);
  216. if (offset > _bsize) return 0;
  217. if (size > _bsize - offset) size = _bsize - offset;
  218. memcpy(buffer, buf + offset, size);
  219. return size;
  220. }
  221. extern uintptr_t heap_end;
  222. extern uintptr_t kernel_heap_alloc_point;
  223. static uint32_t meminfo_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  224. char buf[1024];
  225. unsigned int total = memory_total();
  226. unsigned int free = total - memory_use();
  227. unsigned int kheap = (heap_end - kernel_heap_alloc_point) / 1024;
  228. sprintf(buf,
  229. "MemTotal: %d kB\n"
  230. "MemFree: %d kB\n"
  231. "KHeapUse: %d kB\n"
  232. , total, free, kheap);
  233. size_t _bsize = strlen(buf);
  234. if (offset > _bsize) return 0;
  235. if (size > _bsize - offset) size = _bsize - offset;
  236. memcpy(buffer, buf + offset, size);
  237. return size;
  238. }
  239. static uint32_t uptime_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  240. char buf[1024];
  241. sprintf(buf, "%d.%3d\n", timer_ticks, timer_subticks);
  242. size_t _bsize = strlen(buf);
  243. if (offset > _bsize) return 0;
  244. if (size > _bsize - offset) size = _bsize - offset;
  245. memcpy(buffer, buf + offset, size);
  246. return size;
  247. }
  248. static uint32_t cmdline_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  249. char buf[1024];
  250. extern char * cmdline;
  251. sprintf(buf, "%s\n", cmdline ? cmdline : "");
  252. size_t _bsize = strlen(buf);
  253. if (offset > _bsize) return 0;
  254. if (size > _bsize - offset) size = _bsize - offset;
  255. memcpy(buffer, buf + offset, size);
  256. return size;
  257. }
  258. static uint32_t version_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  259. char buf[1024];
  260. char version_number[512];
  261. sprintf(version_number, __kernel_version_format,
  262. __kernel_version_major,
  263. __kernel_version_minor,
  264. __kernel_version_lower,
  265. __kernel_version_suffix);
  266. sprintf(buf, "%s %s %s %s %s %s\n",
  267. __kernel_name,
  268. version_number,
  269. __kernel_version_codename,
  270. __kernel_build_date,
  271. __kernel_build_time,
  272. __kernel_arch);
  273. size_t _bsize = strlen(buf);
  274. if (offset > _bsize) return 0;
  275. if (size > _bsize - offset) size = _bsize - offset;
  276. memcpy(buffer, buf + offset, size);
  277. return size;
  278. }
  279. static uint32_t compiler_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  280. char buf[1024];
  281. sprintf(buf, "%s\n", __kernel_compiler_version);
  282. size_t _bsize = strlen(buf);
  283. if (offset > _bsize) return 0;
  284. if (size > _bsize - offset) size = _bsize - offset;
  285. memcpy(buffer, buf, size);
  286. return size;
  287. }
  288. extern tree_t * fs_tree; /* kernel/fs/vfs.c */
  289. static void mount_recurse(char * buf, tree_node_t * node, size_t height) {
  290. /* End recursion on a blank entry */
  291. if (!node) return;
  292. char * tmp = malloc(512);
  293. memset(tmp, 0, 512);
  294. char * c = tmp;
  295. /* Indent output */
  296. for (uint32_t i = 0; i < height; ++i) {
  297. c += sprintf(c, " ");
  298. }
  299. /* Get the current process */
  300. struct vfs_entry * fnode = (struct vfs_entry *)node->value;
  301. /* Print the process name */
  302. if (fnode->file) {
  303. c += sprintf(c, "%s → %s 0x%x (%s, %s)", fnode->name, fnode->device, fnode->file, fnode->fs_type, fnode->file->name);
  304. } else {
  305. c += sprintf(c, "%s → (empty)", fnode->name);
  306. }
  307. /* Linefeed */
  308. sprintf(buf+strlen(buf),"%s\n",tmp);
  309. free(tmp);
  310. foreach(child, node->children) {
  311. /* Recursively print the children */
  312. mount_recurse(buf+strlen(buf),child->value, height + 1);
  313. }
  314. }
  315. static uint32_t mounts_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  316. char * buf = malloc(4096);
  317. buf[0] = '\0';
  318. mount_recurse(buf, fs_tree->root, 0);
  319. size_t _bsize = strlen(buf);
  320. if (offset > _bsize) {
  321. free(buf);
  322. return 0;
  323. }
  324. if (size > _bsize - offset) size = _bsize - offset;
  325. memcpy(buffer, buf, size);
  326. free(buf);
  327. return size;
  328. }
  329. static uint32_t netif_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  330. char * buf = malloc(4096);
  331. /* In order to not directly depend on the network module, we dynamically locate the symbols we need. */
  332. void (*ip_ntoa)(uint32_t, char *) = (void (*)(uint32_t,char*))(uintptr_t)hashmap_get(modules_get_symbols(),"ip_ntoa");
  333. struct netif * (*get_netif)(void) = (struct netif *(*)(void))(uintptr_t)hashmap_get(modules_get_symbols(),"get_default_network_interface");
  334. uint32_t (*get_dns)(void) = (uint32_t (*)(void))(uintptr_t)hashmap_get(modules_get_symbols(),"get_primary_dns");
  335. if (get_netif) {
  336. struct netif * netif = get_netif();
  337. char ip[16];
  338. ip_ntoa(netif->source, ip);
  339. char dns[16];
  340. ip_ntoa(get_dns(), dns);
  341. char gw[16];
  342. ip_ntoa(netif->gateway, gw);
  343. if (netif->hwaddr[0] == 0 &&
  344. netif->hwaddr[1] == 0 &&
  345. netif->hwaddr[2] == 0 &&
  346. netif->hwaddr[3] == 0 &&
  347. netif->hwaddr[4] == 0 &&
  348. netif->hwaddr[5] == 0) {
  349. sprintf(buf, "no network\n");
  350. } else {
  351. sprintf(buf,
  352. "ip:\t%s\n"
  353. "mac:\t%2x:%2x:%2x:%2x:%2x:%2x\n"
  354. "device:\t%s\n"
  355. "dns:\t%s\n"
  356. "gateway:\t%s\n"
  357. ,
  358. ip,
  359. netif->hwaddr[0], netif->hwaddr[1], netif->hwaddr[2], netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5],
  360. netif->driver,
  361. dns,
  362. gw
  363. );
  364. }
  365. } else {
  366. sprintf(buf, "no network\n");
  367. }
  368. size_t _bsize = strlen(buf);
  369. if (offset > _bsize) {
  370. free(buf);
  371. return 0;
  372. }
  373. if (size > _bsize - offset) size = _bsize - offset;
  374. memcpy(buffer, buf, size);
  375. free(buf);
  376. return size;
  377. }
  378. static uint32_t modules_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  379. char * buf = malloc(4096);
  380. list_t * hash_keys = hashmap_keys(modules_get_list());
  381. unsigned int soffset = 0;
  382. foreach(_key, hash_keys) {
  383. char * key = (char *)_key->value;
  384. module_data_t * mod_info = hashmap_get(modules_get_list(), key);
  385. soffset += sprintf(&buf[soffset], "0x%x {.init=0x%x, .fini=0x%x} %s",
  386. mod_info->bin_data,
  387. mod_info->mod_info->initialize,
  388. mod_info->mod_info->finalize,
  389. mod_info->mod_info->name);
  390. if (mod_info->deps) {
  391. unsigned int i = 0;
  392. soffset += sprintf(&buf[soffset], " Deps: ");
  393. while (i < mod_info->deps_length) {
  394. soffset += sprintf(&buf[soffset], "%s ", &mod_info->deps[i]);
  395. i += strlen(&mod_info->deps[i]) + 1;
  396. }
  397. }
  398. soffset += sprintf(&buf[soffset], "\n");
  399. }
  400. free(hash_keys);
  401. size_t _bsize = strlen(buf);
  402. if (offset > _bsize) {
  403. free(buf);
  404. return 0;
  405. }
  406. if (size > _bsize - offset) size = _bsize - offset;
  407. memcpy(buffer, buf, size);
  408. free(buf);
  409. return size;
  410. }
  411. extern hashmap_t * fs_types; /* from kernel/fs/vfs.c */
  412. static uint32_t filesystems_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  413. char * buf = malloc(4096);
  414. list_t * hash_keys = hashmap_keys(fs_types);
  415. unsigned int soffset = 0;
  416. foreach(_key, hash_keys) {
  417. char * key = (char *)_key->value;
  418. soffset += sprintf(&buf[soffset], "%s\n", key);
  419. }
  420. free(hash_keys);
  421. size_t _bsize = strlen(buf);
  422. if (offset > _bsize) {
  423. free(buf);
  424. return 0;
  425. }
  426. if (size > _bsize - offset) size = _bsize - offset;
  427. memcpy(buffer, buf, size);
  428. free(buf);
  429. return size;
  430. }
  431. static uint32_t loader_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  432. char * buf = malloc(4096);
  433. if (mboot_ptr->flags & MULTIBOOT_FLAG_LOADER) {
  434. sprintf(buf, "%s\n", mboot_ptr->boot_loader_name);
  435. } else {
  436. buf[0] = '\n';
  437. buf[1] = '\0';
  438. }
  439. size_t _bsize = strlen(buf);
  440. if (offset > _bsize) {
  441. free(buf);
  442. return 0;
  443. }
  444. if (size > _bsize - offset) size = _bsize - offset;
  445. memcpy(buffer, buf, size);
  446. free(buf);
  447. return size;
  448. }
  449. extern char * get_irq_handler(int irq, int chain);
  450. static uint32_t irq_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
  451. char * buf = malloc(4096);
  452. unsigned int soffset = 0;
  453. for (int i = 0; i < 16; ++i) {
  454. soffset += sprintf(&buf[soffset], "irq %d: ", i);
  455. for (int j = 0; j < 4; ++j) {
  456. char * t = get_irq_handler(i, j);
  457. if (!t) break;
  458. soffset += sprintf(&buf[soffset], "%s%s", j ? "," : "", t);
  459. }
  460. soffset += sprintf(&buf[soffset], "\n");
  461. }
  462. size_t _bsize = strlen(buf);
  463. if (offset > _bsize) {
  464. free(buf);
  465. return 0;
  466. }
  467. if (size > _bsize - offset) size = _bsize - offset;
  468. memcpy(buffer, buf, size);
  469. free(buf);
  470. return size;
  471. }
  472. static struct procfs_entry std_entries[] = {
  473. {-1, "cpuinfo", cpuinfo_func},
  474. {-2, "meminfo", meminfo_func},
  475. {-3, "uptime", uptime_func},
  476. {-4, "cmdline", cmdline_func},
  477. {-5, "version", version_func},
  478. {-6, "compiler", compiler_func},
  479. {-7, "mounts", mounts_func},
  480. {-8, "netif", netif_func},
  481. {-9, "modules", modules_func},
  482. {-10,"filesystems", filesystems_func},
  483. {-11,"loader", loader_func},
  484. {-12,"irq", irq_func},
  485. };
  486. static struct dirent * readdir_procfs_root(fs_node_t *node, uint32_t index) {
  487. if (index == 0) {
  488. struct dirent * out = malloc(sizeof(struct dirent));
  489. memset(out, 0x00, sizeof(struct dirent));
  490. out->ino = 0;
  491. strcpy(out->name, ".");
  492. return out;
  493. }
  494. if (index == 1) {
  495. struct dirent * out = malloc(sizeof(struct dirent));
  496. memset(out, 0x00, sizeof(struct dirent));
  497. out->ino = 0;
  498. strcpy(out->name, "..");
  499. return out;
  500. }
  501. if (index == 2) {
  502. struct dirent * out = malloc(sizeof(struct dirent));
  503. memset(out, 0x00, sizeof(struct dirent));
  504. out->ino = 0;
  505. strcpy(out->name, "self");
  506. return out;
  507. }
  508. index -= 3;
  509. if (index < PROCFS_STANDARD_ENTRIES) {
  510. struct dirent * out = malloc(sizeof(struct dirent));
  511. memset(out, 0x00, sizeof(struct dirent));
  512. out->ino = std_entries[index].id;
  513. strcpy(out->name, std_entries[index].name);
  514. return out;
  515. }
  516. int i = index - PROCFS_STANDARD_ENTRIES + 1;
  517. debug_print(WARNING, "%d %d %d", i, index, PROCFS_STANDARD_ENTRIES);
  518. pid_t pid = 0;
  519. foreach(lnode, process_list) {
  520. i--;
  521. if (i == 0) {
  522. process_t * proc = (process_t *)lnode->value;
  523. pid = proc->id;
  524. break;
  525. }
  526. }
  527. if (pid == 0) {
  528. return NULL;
  529. }
  530. struct dirent * out = malloc(sizeof(struct dirent));
  531. memset(out, 0x00, sizeof(struct dirent));
  532. out->ino = pid;
  533. sprintf(out->name, "%d", pid);
  534. return out;
  535. }
  536. static fs_node_t * finddir_procfs_root(fs_node_t * node, char * name) {
  537. if (!name) return NULL;
  538. if (strlen(name) < 1) return NULL;
  539. if (name[0] >= '0' && name[0] <= '9') {
  540. /* XXX process entries */
  541. pid_t pid = atoi(name);
  542. process_t * proc = process_from_pid(pid);
  543. if (!proc) {
  544. return NULL;
  545. }
  546. fs_node_t * out = procfs_procdir_create(proc);
  547. return out;
  548. }
  549. if (!strcmp(name,"self")) {
  550. return procfs_procdir_create((process_t *)current_process);
  551. }
  552. for (unsigned int i = 0; i < PROCFS_STANDARD_ENTRIES; ++i) {
  553. if (!strcmp(name, std_entries[i].name)) {
  554. fs_node_t * out = procfs_generic_create(std_entries[i].name, std_entries[i].func);
  555. return out;
  556. }
  557. }
  558. return NULL;
  559. }
  560. static fs_node_t * procfs_create(void) {
  561. fs_node_t * fnode = malloc(sizeof(fs_node_t));
  562. memset(fnode, 0x00, sizeof(fs_node_t));
  563. fnode->inode = 0;
  564. strcpy(fnode->name, "proc");
  565. fnode->mask = 0555;
  566. fnode->uid = 0;
  567. fnode->gid = 0;
  568. fnode->flags = FS_DIRECTORY;
  569. fnode->read = NULL;
  570. fnode->write = NULL;
  571. fnode->open = NULL;
  572. fnode->close = NULL;
  573. fnode->readdir = readdir_procfs_root;
  574. fnode->finddir = finddir_procfs_root;
  575. fnode->nlink = 1;
  576. fnode->ctime = now();
  577. fnode->mtime = now();
  578. fnode->atime = now();
  579. return fnode;
  580. }
  581. int procfs_initialize(void) {
  582. /* TODO Move this to some sort of config */
  583. vfs_mount("/proc", procfs_create());
  584. debug_print_vfs_tree();
  585. return 0;
  586. }
  587. int procfs_finalize(void) {
  588. return 0;
  589. }
  590. MODULE_DEF(procfs, procfs_initialize, procfs_finalize);