#define BASH_TEST2 (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST)
#define BASH_READ_D ENABLE_HUSH_BASH_COMPAT
-
/* Build knobs */
#define LEAK_HUNTING 0
#define BUILD_AS_NOMMU 0
*/
#define ENABLE_HUSH_DOLLAR_OPS 1
-
#if BUILD_AS_NOMMU
# undef BB_MMU
# undef USE_FOR_NOMMU
} nommu_save_t;
#endif
-
enum {
RES_NONE = 0,
#if ENABLE_HUSH_IF
};
#endif
-
/* set -/+o OPT support. (TODO: make it optional)
* bash supports the following opts:
* allexport off
} while (0)
#endif /* !__U_BOOT__ */
-
#ifndef __U_BOOT__
/* Function prototypes for builtins */
static int builtin_cd(char **argv) FAST_FUNC;
# define debug_print_strings(prefix, vv) ((void)0)
#endif
-
/* Leak hunting. Use hush_leaktool.sh for post-processing.
*/
#if LEAK_HUNTING
# define free(p) xxfree(p)
#endif
-
/* Syntax and runtime errors. They always abort scripts.
* In interactive use they usually discard unparsed and/or unexecuted commands
* and return to the prompt.
return newfd;
}
-
/* Manipulating HFILEs */
static HFILE *hfopen(const char *name)
{
}
#endif /* !__U_BOOT__ */
-
#ifndef __U_BOOT__
/* Basic theory of signal handling in shell
* ========================================
return last_sig;
}
-
static const char *get_cwd(int force)
{
if (force || G.cwd == NULL) {
}
#endif
-
#ifndef __U_BOOT__
/*
* Helpers for "var1=val1 var2=val2 cmd" feature
free(strings);
}
-
/*
* Unicode helper
*/
i->p = s;
}
-
/*
* o_string support
*/
}
}
-
/*** Parsing routines ***/
#ifndef debug_print_tree
return 0;
}
-
#ifndef __U_BOOT__
/* Peek ahead in the input to find out if we have a "&n" construct,
* as in "2>&1", that represents duplicating a file descriptor.
return heredoc_cnt;
}
-
static int run_list(struct pipe *pi);
#if BB_MMU
#define parse_stream(pstring, heredoc_cnt_ptr, input, end_trigger) \
}
}
-
/* Process `cmd` - copy contents until "`" is seen. Complicated by
* \` quoting.
* "Within the backquoted style of command substitution, backslash
}
}
-
/*** Execution routines ***/
/* Expansion can recurse, need forward decls: */
return p;
}
-
static void switch_off_special_sigs(unsigned mask)
{
unsigned sig = 0;
}
#endif /* ENABLE_HUSH_TICK */
-
static void setup_heredoc(struct redir_struct *redir)
{
struct fd_pair pair;
}
#endif /* ENABLE_HUSH_FUNCTIONS */
-
#ifndef __U_BOOT__
#if BB_MMU
#define exec_builtin(to_free, x, argv) \
}
#endif /* !__U_BOOT__ */
-
#ifndef __U_BOOT__
static void execvp_or_die(char **argv) NORETURN;
static void execvp_or_die(char **argv)
return rcode;
}
-
#ifndef __U_BOOT__
static void install_sighandlers(unsigned mask)
{
hush_exit(G.last_exitcode);
}
-
-
/*
* Built-ins
*/
if (l < (unsigned long)p) l = (unsigned long)p;
free(p);
-
# if 0 /* debug */
{
struct mallinfo mi = mallinfo();
Thanks to Martin Fong and others for supplying this.
*/
-
#ifdef WIN32
#define AlignPage(add) (((add) + (malloc_getpagesize-1)) & \
}
-
void* wsbrk (long size)
{
void* tmp;
#endif
-
-
/*
Type declarations
*/
-
struct malloc_chunk
{
INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
An allocated chunk looks like this:
-
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if allocated | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
Where "chunk" is the front of the chunk for the purpose of most of
the malloc code, but "mem" is the pointer that is returned to the
user. "Nextchunk" is the beginning of the next contiguous chunk.
#define aligned_OK(m) (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
-
-
-
/*
Physical chunk operations
*/
-
/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
#define PREV_INUSE 0x1
#define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
-
/* Ptr to next physical malloc_chunk. */
#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
#define prev_chunk(p)\
((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
-
/* Treat space at ptr + offset as a chunk */
#define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s)))
-
-
-
/*
Dealing with use bits
*/
#define clear_inuse_bit_at_offset(p, s)\
(((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
-
-
-
/*
Dealing with size fields
*/
#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
-
-
-
-
/*
Bins
#define top (av_[2]) /* The topmost chunk */
#define last_remainder (bin_at(1)) /* remainder from last split */
-
/*
Because top initially points to its own bin with initial
zero size, thus forcing extension on the first malloc request,
#define is_small_request(nb) (nb < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH)
-
-
/*
To help compensate for the large number of bins, a one-level index
structure is used for bin-by-bin searching. `binblocks' is a
#define mark_binblock(ii) (binblocks_w = (mbinptr)(binblocks_r | idx2binblock(ii)))
#define clear_binblock(ii) (binblocks_w = (mbinptr)(binblocks_r & ~(idx2binblock(ii))))
-
-
-
-
/* Other static bookkeeping data */
/* variables holding tunable values */
#ifdef DEBUG
-
/*
These routines make a number of assertions about the states
of data structures that should be true at all times. If any
}
-
#if __STD_C
static void do_check_free_chunk(mchunkptr p)
#else
/* ... and alignment */
assert(aligned_OK(chunk2mem(p)));
-
/* ... and was allocated at front of an available chunk */
assert(prev_inuse(p));
}
-
#define check_free_chunk(P) do_check_free_chunk(P)
#define check_inuse_chunk(P) do_check_inuse_chunk(P)
#define check_chunk(P) do_check_chunk(P)
#define check_malloced_chunk(P,N)
#endif
-
-
/*
Macro-based internal utilities
*/
-
/*
Linking chunks in bin lists.
Call these only with variables, not arbitrary expressions, as arguments.
putting it ahead of others of same size.
*/
-
#define frontlink(P, S, IDX, BK, FD) \
{ \
if (S < MAX_SMALLBIN_SIZE) \
} \
}
-
/* take a chunk off a list */
#define unlink(P, BK, FD) \
#define clear_last_remainder \
(last_remainder->fd = last_remainder->bk = last_remainder)
-
-
-
-
/* Routines dealing with mmap(). */
#if HAVE_MMAP
assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0);
}
-
-
-
/* Main public routines */
-
/*
Malloc Algorthim:
contiguous memory. Thus, it should be safe to intersperse
mallocs with other sbrk calls.
-
All allocations are made from the the `lowest' part of any found
chunk. (The implementation invariant is that prev_inuse is
always true of any allocated chunk; i.e., that each allocated
}
}
-
/* Try to use top chunk */
/* Require that there be a remainder, ensuring top always exists */
}
-
-
-
/*
free() algorithm :
*/
-
STATIC_IF_MCHECK
#if __STD_C
void fREe_impl(Void_t* mem)
unlink(next, bck, fwd);
}
-
set_head(p, sz | PREV_INUSE);
set_foot(p, sz);
if (!islr)
frontlink(p, sz, idx, bck, fwd);
}
-
-
-
-
/*
Realloc algorithm:
and allowing it would also allow too many other incorrect
usages of realloc to be sensible.
-
*/
-
STATIC_IF_MCHECK
#if __STD_C
Void_t* rEALLOc_impl(Void_t* oldmem, size_t bytes)
newp = oldp = mem2chunk(oldmem);
newsize = oldsize = chunksize(oldp);
-
nb = request2size(bytes);
#if HAVE_MMAP
VALGRIND_MAKE_MEM_DEFINED(oldmem, bytes);
}
-
split: /* split off extra room in old or expanded chunk */
if (newsize - nb >= MINSIZE) /* split off remainder */
return chunk2mem(newp);
}
-
-
-
/*
memalign algorithm:
*/
-
STATIC_IF_MCHECK
#if __STD_C
Void_t* mEMALIGn_impl(size_t alignment, size_t bytes)
}
-
-
-
/*
valloc just invokes memalign with alignment argument equal
to the page size of the system (or as near to this as can
that will accommodate request
*/
-
#if __STD_C
Void_t* pvALLOc(size_t bytes)
#else
INTERNAL_SIZE_T sz = n * elem_size;
-
/* check if expand_top called, in which case don't need to clear */
#if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT)
#if MORECORE_CLEARS
/* Two optional cases in which clearing not necessary */
-
#if HAVE_MMAP
if (chunk_is_mmapped(p)) return mem;
#endif
}
#endif
-
#ifdef MCHECK_HEAP_PROTECTION
#include "mcheck_core.inc.h"
#if !__STD_C
// mcheck API }
#endif
-
/*
Malloc_trim gives memory back to the system (via negative
}
}
-
-
/*
malloc_usable_size:
}
}
-
-
-
/* Utility to update current_mallinfo for malloc_stats and mallinfo() */
#ifdef DEBUG
}
#endif /* DEBUG */
-
-
/*
malloc_stats:
}
#endif /* DEBUG */
-
-
-
/*
mallopt: