sysinfo.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include <strings.h>
  9. #include <errno.h>
  10. #define MEMINFO_FILE "/proc/meminfo"
  11. #define MTAB_FILE "/etc/mtab"
  12. #define BAD_OPEN_MESSAGE \
  13. "Error: /proc must be mounted\n" \
  14. " To mount /proc at boot you need an /etc/fstab line like:\n" \
  15. " /proc /proc proc defaults\n" \
  16. " In the meantime, run \"mount /proc /proc -t proc\"\n"
  17. /* This macro opens filename only if necessary and seeks to 0 so
  18. * that successive calls to the functions are more efficient.
  19. * It also reads the current contents of the file into the global buf.
  20. */
  21. #define FILE_TO_BUF(filename) do{ \
  22. static int fd, local_n; \
  23. if ((fd = open(filename, O_RDONLY)) == -1) { \
  24. fputs(BAD_OPEN_MESSAGE, stderr); \
  25. fflush(NULL); \
  26. return -102; \
  27. } \
  28. lseek(fd, 0L, SEEK_SET); \
  29. if ((local_n = read(fd, buf, sizeof buf - 1)) < 0) { \
  30. perror(filename); \
  31. fflush(NULL); \
  32. return -103; \
  33. } \
  34. buf[local_n] = '\0'; \
  35. close(fd); \
  36. }while(0)
  37. typedef struct mem_table_struct {
  38. const char *name; /* memory type name */
  39. unsigned long *slot; /* slot in return struct */
  40. } mem_table_struct;
  41. static int compare_mem_table_structs(const void *a, const void *b){
  42. return strcmp(((const mem_table_struct*)a)->name,((const mem_table_struct*)b)->name);
  43. }
  44. size_t fastwriter_get_free_memory(void){
  45. char buf[4096];
  46. unsigned long kb_main_buffers, kb_main_cached, kb_main_free;
  47. char namebuf[16]; /* big enough to hold any row name */
  48. mem_table_struct findme = { namebuf, NULL};
  49. mem_table_struct *found;
  50. char *head;
  51. char *tail;
  52. const mem_table_struct mem_table[] = {
  53. {"Buffers", &kb_main_buffers}, // important
  54. {"Cached", &kb_main_cached}, // important
  55. {"MemFree", &kb_main_free}, // important
  56. };
  57. const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct);
  58. FILE_TO_BUF(MEMINFO_FILE);
  59. head = buf;
  60. for(;;){
  61. tail = strchr(head, ':');
  62. if(!tail) break;
  63. *tail = '\0';
  64. if(strlen(head) >= sizeof(namebuf)){
  65. head = tail+1;
  66. goto nextline;
  67. }
  68. strcpy(namebuf,head);
  69. found = bsearch(&findme, mem_table, mem_table_count,
  70. sizeof(mem_table_struct), compare_mem_table_structs
  71. );
  72. head = tail+1;
  73. if(!found) goto nextline;
  74. *(found->slot) = strtoul(head,&tail,10);
  75. nextline:
  76. tail = strchr(head, '\n');
  77. if(!tail) break;
  78. head = tail+1;
  79. }
  80. return (kb_main_buffers + kb_main_cached + kb_main_free) * 1024;
  81. }
  82. int fastwriter_get_file_fs(const char *fname, size_t size, char *fs) {
  83. int err = 0;
  84. char buf[4096];
  85. char *fn;
  86. char *head;
  87. char *tail;
  88. size_t len, max = 0;
  89. struct stat st;
  90. if ((!fname)||(!fs)||(size < 3)) return EINVAL;
  91. if (*fname == '/') {
  92. fn = (char*)fname;
  93. } else {
  94. if (!getcwd(buf, 4095)) return errno;
  95. fn = malloc(strlen(fname) + strlen(buf) + 2);
  96. if (!fn) return ENOMEM;
  97. sprintf(fn, "%s/%s", buf, fname);
  98. }
  99. if (!stat(fn, &st)) {
  100. if (!S_ISREG(st.st_mode)) {
  101. strcpy(fs, "raw");
  102. goto clean;
  103. }
  104. }
  105. FILE_TO_BUF(MTAB_FILE);
  106. head = buf;
  107. for(;;){
  108. head = strchr(head, ' ');
  109. if(!head) break;
  110. head += 1;
  111. tail = strchr(head, ' ');
  112. if(!tail) break;
  113. *tail = '\0';
  114. len = strlen(head);
  115. if((len <= max)||(strncmp(head, fn, len))) {
  116. head = tail+1;
  117. goto nextline;
  118. }
  119. head = tail + 1;
  120. tail = strchr(head, ' ');
  121. if(!tail) break;
  122. *tail = '\0';
  123. if (!strncasecmp(head,"root",4)) {
  124. head = tail+1;
  125. goto nextline;
  126. }
  127. max = len;
  128. if (strlen(head) >= size) err = EFAULT;
  129. else {
  130. err = 0;
  131. strcpy(fs, head);
  132. }
  133. head = tail+1;
  134. nextline:
  135. tail = strchr(head, '\n');
  136. if(!tail) break;
  137. head = tail+1;
  138. }
  139. clean:
  140. if (fn != fname) free(fn);
  141. return err;
  142. }