📄 ash.c
字号:
static int rootshell;static void readcmdfile(char *);static void cmdloop(int);/* $NetBSD: memalloc.h,v 1.13 2003/01/22 20:36:04 dsl Exp $ */struct stackmark { struct stack_block *stackp; char *stacknxt; size_t stacknleft; struct stackmark *marknext;};/* minimum size of a block */#define MINSIZE SHELL_ALIGN(504)struct stack_block { struct stack_block *prev; char space[MINSIZE];};static struct stack_block stackbase;static struct stack_block *stackp = &stackbase;static struct stackmark *markp;static char *stacknxt = stackbase.space;static size_t stacknleft = MINSIZE;static char *sstrend = stackbase.space + MINSIZE;static int herefd = -1;static pointer ckmalloc(size_t);static pointer ckrealloc(pointer, size_t);static char *savestr(const char *);static pointer stalloc(size_t);static void stunalloc(pointer);static void setstackmark(struct stackmark *);static void popstackmark(struct stackmark *);static void growstackblock(void);static void *growstackstr(void);static char *makestrspace(size_t, char *);static char *stnputs(const char *, size_t, char *);static char *stputs(const char *, char *);static inline char *_STPUTC(char c, char *p) { if (p == sstrend) p = growstackstr(); *p++ = c; return p;}#define stackblock() ((void *)stacknxt)#define stackblocksize() stacknleft#define STARTSTACKSTR(p) ((p) = stackblock())#define STPUTC(c, p) ((p) = _STPUTC((c), (p)))#define CHECKSTRSPACE(n, p) \ ({ \ char *q = (p); \ size_t l = (n); \ size_t m = sstrend - q; \ if (l > m) \ (p) = makestrspace(l, q); \ 0; \ })#define USTPUTC(c, p) (*p++ = (c))#define STACKSTRNUL(p) ((p) == sstrend? (p = growstackstr(), *p = '\0') : (*p = '\0'))#define STUNPUTC(p) (--p)#define STTOPC(p) p[-1]#define STADJUST(amount, p) (p += (amount))#define grabstackstr(p) stalloc((char *)(p) - (char *)stackblock())#define ungrabstackstr(s, p) stunalloc((s))#define stackstrend() ((void *)sstrend)#define ckfree(p) free((pointer)(p))/* $NetBSD: mystring.h,v 1.10 2002/11/24 22:35:42 christos Exp $ */#define DOLATSTRLEN 4static char *prefix(const char *, const char *);static int number(const char *);static int is_number(const char *);static char *single_quote(const char *);static char *sstrdup(const char *);#define equal(s1, s2) (strcmp(s1, s2) == 0)#define scopy(s1, s2) ((void)strcpy(s2, s1))/* $NetBSD: options.h,v 1.16 2003/01/22 20:36:04 dsl Exp $ */struct shparam { int nparam; /* # of positional parameters (without $0) */ unsigned char malloc; /* if parameter list dynamically allocated */ char **p; /* parameter list */#ifdef CONFIG_ASH_GETOPTS int optind; /* next parameter to be processed by getopts */ int optoff; /* used by getopts */#endif};#define eflag optlist[0]#define fflag optlist[1]#define Iflag optlist[2]#define iflag optlist[3]#define mflag optlist[4]#define nflag optlist[5]#define sflag optlist[6]#define xflag optlist[7]#define vflag optlist[8]#define Cflag optlist[9]#define aflag optlist[10]#define bflag optlist[11]#define uflag optlist[12]#define qflag optlist[13]#ifdef DEBUG#define nolog optlist[14]#define debug optlist[15]#define NOPTS 16#else#define NOPTS 14#endif/* $NetBSD: options.c,v 1.33 2003/01/22 20:36:04 dsl Exp $ */static const char *const optletters_optnames[NOPTS] = { "e" "errexit", "f" "noglob", "I" "ignoreeof", "i" "interactive", "m" "monitor", "n" "noexec", "s" "stdin", "x" "xtrace", "v" "verbose", "C" "noclobber", "a" "allexport", "b" "notify", "u" "nounset", "q" "quietprofile",#ifdef DEBUG "\0" "nolog", "\0" "debug",#endif};#define optletters(n) optletters_optnames[(n)][0]#define optnames(n) (&optletters_optnames[(n)][1])static char optlist[NOPTS];static char *arg0; /* value of $0 */static struct shparam shellparam; /* $@ current positional parameters */static char **argptr; /* argument list for builtin commands */static char *optionarg; /* set by nextopt (like getopt) */static char *optptr; /* used by nextopt */static char *minusc; /* argument to -c option */static void procargs(int, char **);static void optschanged(void);static void setparam(char **);static void freeparam(volatile struct shparam *);static int shiftcmd(int, char **);static int setcmd(int, char **);static int nextopt(const char *);/* $NetBSD: redir.h,v 1.14 2002/11/24 22:35:43 christos Exp $ *//* flags passed to redirect */#define REDIR_PUSH 01 /* save previous values of file descriptors */#define REDIR_SAVEFD2 03 /* set preverrout */union node;static void redirect(union node *, int);static void popredir(int);static void clearredir(int);static int copyfd(int, int);static int redirectsafe(union node *, int);/* $NetBSD: show.h,v 1.6 2003/01/22 20:36:04 dsl Exp $ */#ifdef DEBUGstatic void showtree(union node *);static void trace(const char *, ...);static void tracev(const char *, va_list);static void trargs(char **);static void trputc(int);static void trputs(const char *);static void opentrace(void);#endif/* $NetBSD: trap.h,v 1.16 2002/11/24 22:35:43 christos Exp $ *//* trap handler commands */static char *trap[NSIG];/* current value of signal */static char sigmode[NSIG - 1];/* indicates specified signal received */static char gotsig[NSIG - 1];static void clear_traps(void);static void setsignal(int);static void ignoresig(int);static void onsig(int);static void dotrap(void);static void setinteractive(int);static void exitshell(void) __attribute__((__noreturn__));static int decode_signal(const char *, int);/* * This routine is called when an error or an interrupt occurs in an * interactive shell and control is returned to the main command loop. */static voidreset(void){ /* from eval.c: */ { evalskip = 0; loopnest = 0; funcnest = 0; } /* from input.c: */ { parselleft = parsenleft = 0; /* clear input buffer */ popallfiles(); } /* from parser.c: */ { tokpushback = 0; checkkwd = 0; } /* from redir.c: */ { clearredir(0); }}#ifdef CONFIG_ASH_ALIASstatic struct alias *atab[ATABSIZE];static void setalias(const char *, const char *);static struct alias *freealias(struct alias *);static struct alias **__lookupalias(const char *);static voidsetalias(const char *name, const char *val){ struct alias *ap, **app; app = __lookupalias(name); ap = *app; INTOFF; if (ap) { if (!(ap->flag & ALIASINUSE)) { ckfree(ap->val); } ap->val = savestr(val); ap->flag &= ~ALIASDEAD; } else { /* not found */ ap = ckmalloc(sizeof (struct alias)); ap->name = savestr(name); ap->val = savestr(val); ap->flag = 0; ap->next = 0; *app = ap; } INTON;}static intunalias(const char *name){ struct alias **app; app = __lookupalias(name); if (*app) { INTOFF; *app = freealias(*app); INTON; return (0); } return (1);}static voidrmaliases(void){ struct alias *ap, **app; int i; INTOFF; for (i = 0; i < ATABSIZE; i++) { app = &atab[i]; for (ap = *app; ap; ap = *app) { *app = freealias(*app); if (ap == *app) { app = &ap->next; } } } INTON;}static struct alias *lookupalias(const char *name, int check){ struct alias *ap = *__lookupalias(name); if (check && ap && (ap->flag & ALIASINUSE)) return (NULL); return (ap);}/* * TODO - sort output */static intaliascmd(int argc, char **argv){ char *n, *v; int ret = 0; struct alias *ap; if (argc == 1) { int i; for (i = 0; i < ATABSIZE; i++) for (ap = atab[i]; ap; ap = ap->next) { printalias(ap); } return (0); } while ((n = *++argv) != NULL) { if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */ if ((ap = *__lookupalias(n)) == NULL) { fprintf(stderr, "%s: %s not found\n", "alias", n); ret = 1; } else printalias(ap); } else { *v++ = '\0'; setalias(n, v); } } return (ret);}static intunaliascmd(int argc, char **argv){ int i; while ((i = nextopt("a")) != '\0') { if (i == 'a') { rmaliases(); return (0); } } for (i = 0; *argptr; argptr++) { if (unalias(*argptr)) { fprintf(stderr, "%s: %s not found\n", "unalias", *argptr); i = 1; } } return (i);}static struct alias *freealias(struct alias *ap) { struct alias *next; if (ap->flag & ALIASINUSE) { ap->flag |= ALIASDEAD; return ap; } next = ap->next; ckfree(ap->name); ckfree(ap->val); ckfree(ap); return next;}static voidprintalias(const struct alias *ap) { out1fmt("%s=%s\n", ap->name, single_quote(ap->val));}static struct alias **__lookupalias(const char *name) { unsigned int hashval; struct alias **app; const char *p; unsigned int ch; p = name; ch = (unsigned char)*p; hashval = ch << 4; while (ch) { hashval += ch; ch = (unsigned char)*++p; } app = &atab[hashval % ATABSIZE]; for (; *app; app = &(*app)->next) { if (equal(name, (*app)->name)) { break; } } return app;}#endif /* CONFIG_ASH_ALIAS *//* $NetBSD: cd.c,v 1.30 2003/01/22 20:36:03 dsl Exp $ *//* * The cd and pwd commands. */#define CD_PHYSICAL 1#define CD_PRINT 2static int docd(const char *, int);static int cdopt(void);static char *curdir = nullstr; /* current working directory */static char *physdir = nullstr; /* physical working director
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -