PageRenderTime 36ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/servers/filesystems/procfs/root.c

https://bitbucket.org/prem.mallappa/fmios
C | 151 lines | 103 code | 16 blank | 32 comment | 14 complexity | 1737d06f4e0c51066abce2a5c84deb89 MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0
  1. /*
  2. * root.c
  3. * Routines for the root of the proc hierarchy
  4. */
  5. #include "proc.h"
  6. #include <sys/fs.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. void
  10. proc_inval(struct msg *m, struct file *f)
  11. {
  12. msg_err(m->m_sender, EINVAL);
  13. }
  14. void
  15. proc_inval_rw(struct msg *m, struct file *f, uint x)
  16. {
  17. msg_err(m->m_sender, EINVAL);
  18. }
  19. /*
  20. * root_open()
  21. * Open a file in the root directory, i.e., a pid or the kernel stats
  22. */
  23. static void
  24. root_open(struct msg *m, struct file *f)
  25. {
  26. if (!strcmp(m->m_buf, "kernel")) {
  27. f->f_pos = 0L;
  28. f->f_ops = &kernel_ops;
  29. m->m_buflen = m->m_nseg = m->m_arg = m->m_arg1 = 0;
  30. msg_reply(m->m_sender, m);
  31. return;
  32. }
  33. f->f_pid = atoi(m->m_buf);
  34. if (proc_pstat(f) == 0) {
  35. f->f_pos = 0L;
  36. f->f_ops = &proc_ops;
  37. m->m_buflen = m->m_nseg = m->m_arg = m->m_arg1 = 0;
  38. msg_reply(m->m_sender, m);
  39. return;
  40. }
  41. msg_err(m->m_sender, ESRCH);
  42. }
  43. /*
  44. * Read the root directory, i.e., the list of pids. We actually did all the
  45. * pstat()s when first attached to the root.
  46. */
  47. static void
  48. root_read(struct msg *m, struct file *f, uint dummy)
  49. {
  50. char *buf;
  51. int x, len;
  52. /*
  53. * Get the latest pid list
  54. */
  55. if (!f->f_active) {
  56. if ((f->f_active = proclist_pstat(f)) == -1) {
  57. f->f_active = 0;
  58. msg_err(m->m_sender, strerror());
  59. }
  60. }
  61. /*
  62. * Get a buffer of the requested size, but put a sanity
  63. * cap on it.
  64. */
  65. len = MIN(m->m_arg, 256);
  66. if ((buf = malloc(len + 1)) == 0) {
  67. msg_err(m->m_sender, strerror());
  68. return;
  69. }
  70. /*
  71. * Copy as many pids as will fit into the buffer.
  72. */
  73. buf[0] = '\0';
  74. if (!f->f_pos) {
  75. strcpy(buf, "kernel\n");
  76. }
  77. for (x = strlen(buf); x < len; ) {
  78. char pid[8];
  79. /*
  80. * If EOF, return what we have.
  81. */
  82. if (f->f_pos >= f->f_active) {
  83. f->f_active = 0;
  84. break;
  85. }
  86. /*
  87. * If the next entry won't fit, return
  88. * what we have.
  89. */
  90. sprintf(pid, "%lu", f->f_proclist[f->f_pos]);
  91. if ((x + strlen(pid) + 1) >= len) {
  92. break;
  93. }
  94. /*
  95. * Add entry and a newline.
  96. */
  97. strcat(buf + x, pid);
  98. strcat(buf + x, "\n");
  99. x += (strlen(pid) + 1);
  100. f->f_pos++;
  101. }
  102. m->m_buf = buf;
  103. m->m_arg = m->m_buflen = x;
  104. m->m_nseg = (x ? 1 : 0);
  105. m->m_arg1 = 0;
  106. msg_reply(m->m_sender, m);
  107. free(buf);
  108. }
  109. static void
  110. root_stat(struct msg *m, struct file *f)
  111. {
  112. char buf[MAXSTAT];
  113. if ((f->f_active = proclist_pstat(f)) == -1) {
  114. f->f_active = 0;
  115. msg_err(m->m_sender, strerror());
  116. return;
  117. }
  118. sprintf(buf,
  119. "perm=1/1\nacc=7/0/0\nsize=%d\ntype=d\nowner=0\ninode=0\n",
  120. f->f_active);
  121. f->f_active = 0;
  122. m->m_buf = buf;
  123. m->m_arg = m->m_buflen = strlen(buf);
  124. m->m_nseg = 1;
  125. m->m_arg1 = 0;
  126. msg_reply(m->m_sender, m);
  127. }
  128. struct file_ops root_ops = {
  129. root_open,
  130. proc_seek, /* seek */
  131. root_read, /* read */
  132. proc_inval_rw, /* write */
  133. root_stat, /* stat */
  134. proc_inval, /* wstat */
  135. };