SHARE
TWEET

Untitled

a guest Nov 16th, 2019 91 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 'd': {
  119.                 char *str = &line[2];
  120.                 struct bos_entry *entry = first_entry;
  121.                 while ((void*)entry < end) {
  122.                     if(entry->allocated && str == entry[1]){
  123.                         entry->allocated = 0;
  124.                     }
  125.                 }
  126.             }
  127.             case 'L': {
  128.                 struct bos_entry *entry = first_entry;
  129.                 int i = 1;
  130.                 while ((void*)entry < end) {
  131.                     printf("Entry #%d of size: %d\n", i, entry->size);
  132.                     printf("%s\n", (char*)&entry[1]);
  133.                     entry = (struct bos_entry *) ((char *) entry + entry->size);
  134.                     i++;
  135.                 }
  136.             }
  137.                 break; // break from the switch statement
  138.         }
  139.         free(line);
  140.         n = 0;
  141.         line = 0;
  142.     }
  143.     return 0;
  144. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top