/* The malloc() function allocates size bytes and returns a pointer to * the allocated memory. The memory is not initialized. If size is 0, * then malloc() returns either NULL, or a unique pointer value that can * later be successfully passed to free(). * ---- * Implementation notes: * So, somebody wants a block of memory... fine! Here's the game * plan for getting them said memory: * * 1) Scan each block in our free list to see if any of them are * big enough. If we find one that is big enough, we will * either use that memory as-is or chunk it into a couple smaller * pieces (part of which is used, the other which is a new * entry in the free linked list. * 2) If we do not find an item in the free list, we will add the * new block onto the end of our heap. We will attempt to expand * the heap if needed. */ void * po_malloc(size_t size) { block_header_t *current_header, *new_free_header, *block_header; void *memory_to_use = NULL; const size_t size_plus_header = size + sizeof(block_header_t); new_free_header = block_header = NULL; current_header = free_ll_head; while (current_header) { if (current_header->block_length >= size) { memory_to_use = FREE_BLOCK_MEMORY(current_header); if (current_header->block_length > size_plus_header) { new_free_header = (block_header_t *)((unsigned long)memory_to_use + size); new_free_header->block_length = current_header->block_length - size; ll_replace(current_header, new_free_header); } else { ll_remove(current_header); } return memory_to_use; } else { current_header = current_header->next_free_chunk; } } // if we are here, we didn't get what we needed from scanning the // freed list, tack on to the end of memory size_t expand_size; if (current_header) { expand_size = (size_plus_header - current_header->block_length); } else { expand_size = size_plus_header; } block_header = (block_header_t *)sbrk(expand_size); memory_to_use = FREE_BLOCK_MEMORY(block_header); if (!block_header) { /* failed to allocate more memory, return NULL */ return NULL; } /* current_header points to end of current LL unless first */ block_header->next_free_chunk = NULL; block_header->prev_free_chunk = NULL; block_header->block_length = size; return memory_to_use; }
static void write_cf(void) { char tmp[0x100], rv[0x40]; struct conf_item *ci = NULL; char *lp, *cp; int add, i; char *cfname = get_confname(); int cfld = ll_create(); FILE *fd = fopen(cfname, "w"); if (fd == NULL) err_sys("failed to open configuration file '%s'", cfname); for (ll_reset(conf_items); (ci = ll_getall(conf_items)); ) { if (ci->type != t_sep && ci->type != t_func && (!ci->dep || (ci->dep && *ci->dep))) { switch (ci->type) { case t_int: sprintf(rv, "%d", *ci->v.i); break; case t_list: if (!argv_count(ci->list)) continue; sprintf(rv, "%s", ci->list[*ci->v.i]); str_tolower(rv); break; case t_sep: case t_func: break; } add = 1; for (i = 0; i < ll_size(cfld); i++) { lp = ll_get(cfld, i); cp = lp += strspn(lp, " "); if (!strncasecmp(cp, ci->cfname, strcspn(cp, " =")) && strlen(ci->cfname) == strcspn(cp, " =")) { add = 0; cp += strcspn(cp, "=") + 1; cp += strspn(cp, " "); strncpy(tmp, cp, strcspn(cp, " #\n")); if (strcasecmp(tmp, rv)) { strncpy(tmp, lp, strcspn(lp, " =")); tmp[strcspn(lp, " =")] = '\0'; strcat(tmp, " = "); strcat(tmp, rv); strcat(tmp, "\n"); ll_replace(cfld, i, "s", tmp); } } } if (add) { strcpy(tmp, ci->cfname); strcat(tmp, " = "); strcat(tmp, rv); strcat(tmp, "\n"); ll_push(cfld, "s", tmp); } } } for (ll_reset(cfld); (lp = ll_getall(cfld)); ) fputs(lp, fd); fclose(fd); ll_destroy(cfld); free(cfname); }