Guest User

Untitled

a guest
Nov 16th, 2019
96
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/mman.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <sys/stat.h>
  7. #include <sys/types.h>
  8. #include <memory.h>
  9.  
  10. const int INIT_SIZE = 64 * 1024;
  11.  
  12. #pragma pack(1)
  13. struct bos_hdr {
  14. int magic; // must be set to 0xb055;
  15. union {
  16. char padding[16];
  17. } u;
  18. };
  19.  
  20. struct bos_entry {
  21. int allocated:1; // will be non-zero if allocated
  22. int size; // includes the size of bos_entry
  23. union {
  24. char padding[8];
  25. } u;
  26. };
  27.  
  28. #pragma pack()
  29.  
  30. int main(int argc, char **argv) {
  31. if (argc != 2) {
  32. printf("USAGE: %s bos_filename\n", argv[0]);
  33. exit(2);
  34. }
  35. int fd = open(argv[1], O_CREAT | O_RDWR, 0777);
  36. if (fd == -1) {
  37. perror(argv[1]);
  38. exit(3);
  39. }
  40.  
  41. void *base = mmap(NULL, 1024*1024, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
  42. void *end;
  43. struct bos_hdr *hdr = base;
  44. struct bos_entry *first_entry = (struct bos_entry *)(hdr+1);
  45.  
  46. struct stat stat;
  47. if (fstat(fd, &stat) == -1) {
  48. perror("fstat");
  49. exit(4);
  50. }
  51. if (stat.st_size == 0) {
  52. ftruncate(fd, INIT_SIZE);
  53. memset(hdr, 0, sizeof *hdr);
  54. hdr->magic = 0xb055;
  55. memset(first_entry, 0, sizeof *first_entry);
  56. first_entry->size = INIT_SIZE - sizeof *hdr;
  57. end = (char*)base + INIT_SIZE;
  58. } else {
  59. end = (char*)base + stat.st_size;
  60. }
  61.  
  62. size_t n;
  63. char *line = NULL;
  64. while (getline(&line, &n, stdin) > 0) {
  65. // remove the newline
  66. size_t endi = strlen(line) - 1;
  67. if (line[endi] == '\n') {
  68. line[endi] = '\0';
  69. }
  70. switch(line[0]) {
  71. // need to add 'd'
  72. case 'l': {
  73. struct bos_entry *entry = first_entry;
  74. while ((void*)entry < end) {
  75. if (entry->allocated) {
  76. printf("%s\n", (char*)&entry[1]);
  77. }
  78. entry = (struct bos_entry *) ((char *) entry + entry->size);
  79. }
  80. }
  81. break; // break from the switch statement
  82. case 'a': {
  83. // we should check for duplicates first!
  84. char *str = &line[2];
  85. int smallestLeftover = 0;
  86. struct bos_entry *bestFitEntry = NULL;
  87. struct bos_entry *entry = first_entry;
  88. while ((void*)entry < end) {
  89. if (!entry->allocated) {
  90. // split it (note this should be fixed so that it can grow if needed
  91. int needed_size = sizeof(*entry) + strlen(str) + 1;
  92. int left_over = entry->size - needed_size;
  93. if (left_over < sizeof(*entry) && smallestLeftover < left_over) {
  94. //smallestLeftover = left_over;
  95. //bestFitEntry = entry;
  96. // if we don't have enough left over for an entry struct, we just
  97. // use it here and it will be internal fragmentation
  98. needed_size = entry->size;
  99. left_over = 0;
  100. }
  101. if (entry->size < needed_size) {
  102. printf("hmmm, you need to grow!!!\n");
  103. exit(6);
  104. }
  105. entry->size = needed_size;
  106. entry->allocated = 1;
  107. strcpy((char *) &entry[1], str);
  108. if (left_over > 0) {
  109. entry = (struct bos_entry *) ((char *) entry + entry->size);
  110. memset(entry, 0, sizeof *entry);
  111. entry->size = left_over;
  112. }
  113. break;
  114. }
  115. entry = (struct bos_entry *) ((char *) entry + entry->size);
  116. }
  117. }
  118. case 'L': {
  119. struct bos_entry *entry = first_entry;
  120. int i = 1;
  121. while ((void*)entry < end) {
  122. printf("Entry #: %d of size: %d\n", i, entry->size);
  123. printf("%s\n", (char*)&entry[1]);
  124. entry = (struct bos_entry *) ((char *) entry + entry->size);
  125. }
  126. }
  127. break; // break from the switch statement
  128. }
  129. free(line);
  130. n = 0;
  131. line = 0;
  132. }
  133. return 0;
  134. }
RAW Paste Data