/* 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;
}
Example #2
0
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);
}