void exec(t_env *envp, char *buffer) { char **tab; char *link; char **path; int i; tab = my_str_to_wordtab(buffer); while (envp != NULL && my_strcmp(envp->name, "PATH") != 0) envp = envp->next; if (envp != NULL) { path = my_wordtab(envp->content); i = 0; while (tab[0] != NULL && path != NULL && path[i] != NULL) { link = link_cat(tab[0], path[i]); access(link, X_OK) == 0 ? execve(link, tab, environ) : i++; free(link); } } if (tab[0] != NULL) access(tab[0], X_OK) == 0 ? execve(tab[0], tab, environ) : i++; if (tab[0] != NULL) my_printf("[%s] : command not found\n", tab[0]); make_free(&tab, &path); }
/* find_block -- find a free block of specified size */ static header *find_block(unsigned size, unsigned objsize) { header *h = NULL, *h2; int i = min(size/GC_PAGESIZE, BIG_BLOCK); ASSERT(size % GC_PAGESIZE == 0); do { for (headers(h2, free_list[i])) { /* This always succeeds for small blocks, and gives first-fit allocation for big blocks. */ if (size <= h2->h_size) { h = h2; break; } } i++; } while (h == NULL && i <= BIG_BLOCK); if (h == NULL) { /* No suitable block was found. Get a big chunk. */ unsigned chunk = max(size, CHUNK_SIZE); GC_TRACE("[ex]"); ASSERT(chunk % GC_PAGESIZE == 0); h = alloc_header(); h->h_memory = (uchar *) get_memory(chunk); h->h_size = chunk; /* Add to the free list for merging and page table setup */ h = free_block(h, FALSE); } ASSERT(h->h_memory != NULL && h->h_size >= size); unlink(h); if (size < h->h_size) { /* Split the block, and return the waste to the free list. It's best to use header h for the waste: that way, we don't have to reset lots of page table entries when we chip a small piece off a big block. */ h2 = alloc_header(); h2->h_memory = h->h_memory; h2->h_size = size; page_setup(h2->h_memory, size, h2); h->h_memory += size; h->h_size -= size; make_free(h); h = h2; } h->h_objsize = objsize; h->h_epoch = gencount; return h; }
/* free_block -- free a block, merging it with its neighbours */ static header *free_block(header *h, bool mapped) { /* Mapped is true if this memory is being recycled: it's already in the page table, but we'll need to zero it. */ header *prev = left_neighbour(h), *next = right_neighbour(h); /* Base and size of area where page table needs updating */ uchar *pg_memory = h->h_memory; unsigned pg_size = (mapped ? 0 : h->h_size); #ifdef TRACE if (debug['l']) { printf("Freeing block at %p, size %#x\n", h->h_memory, h->h_size); if (prev == NULL) printf("prev=null, "); else printf("prev=%p, ", prev->h_memory); if (next == NULL) printf("next=null\n"); else printf("next=%p\n", next->h_memory); } #endif if (mapped) memset(h->h_memory, 0, h->h_size); if (prev != NULL && prev->h_objsize == 0) { DEBUG_PRINT('l', ("Merging with prev\n")); unlink(prev); prev->h_size += h->h_size; pg_memory = h->h_memory; pg_size = h->h_size; free_header(h); h = prev; } if (next != NULL && next->h_objsize == 0) { DEBUG_PRINT('l', ("Merging with next\n")); unlink(next); next->h_memory = h->h_memory; next->h_size += h->h_size; pg_memory = h->h_memory; pg_size = h->h_size; free_header(h); h = next; } if (pg_size > 0) page_setup(pg_memory, pg_size, h); make_free(h); /* Return the merged block */ return h; }