📄 ash.c
字号:
/* vi: set sw=4 ts=4: *//* * ash shell port for busybox * * Copyright (c) 1989, 1991, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Copyright (c) 1997-2003 Herbert Xu <herbert@debian.org> * was re-ported from NetBSD and debianized. * * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Original BSD copyright notice is retained at the end of this file. *//* * rewrite arith.y to micro stack based cryptic algorithm by * Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com> * * Modified by Paul Mundt <lethal@linux-sh.org> (c) 2004 to support * dynamic variables. * * Modified by Vladimir Oleynik <dzo@simtreas.ru> (c) 2001-2004 to be * used in busybox and size optimizations, * rewrote arith (see notes to this), added locale support, * rewrote dynamic variables. * *//* * The follow should be set to reflect the type of system you have: * JOBS -> 1 if you have Berkeley job control, 0 otherwise. * define SYSV if you are running under System V. * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) * define DEBUG=2 to compile in and turn on debugging. * * When debugging is on, debugging info will be written to ./trace and * a quit signal will generate a core dump. */#define IFS_BROKEN#define PROFILE 0#ifdef DEBUG#define _GNU_SOURCE#endif#include <sys/types.h>#include <sys/cdefs.h>#include <sys/ioctl.h>#include <sys/param.h>#include <sys/resource.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/wait.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <stdarg.h>#include <stddef.h>#include <assert.h>#include <ctype.h>#include <dirent.h>#include <errno.h>#include <fcntl.h>#include <limits.h>#include <paths.h>#include <setjmp.h>#include <signal.h>#include <stdint.h>#include <sysexits.h>#include <time.h>#include <fnmatch.h>#include "busybox.h"#include "pwd_.h"#ifdef CONFIG_ASH_JOB_CONTROL#define JOBS 1#else#undef JOBS#endif#if JOBS#include <termios.h>#endif#include "cmdedit.h"#ifdef __GLIBC__/* glibc sucks */static int *dash_errno;#undef errno#define errno (*dash_errno)#endif#if defined(__uClinux__)#error "Do not even bother, ash will not run on uClinux"#endif#ifdef DEBUG#define _DIAGASSERT(assert_expr) assert(assert_expr)#else#define _DIAGASSERT(assert_expr)#endif#ifdef CONFIG_ASH_ALIAS/* $NetBSD: alias.h,v 1.5 2002/11/24 22:35:38 christos Exp $ */#define ALIASINUSE 1#define ALIASDEAD 2struct alias { struct alias *next; char *name; char *val; int flag;};static struct alias *lookupalias(const char *, int);static int aliascmd(int, char **);static int unaliascmd(int, char **);static void rmaliases(void);static int unalias(const char *);static void printalias(const struct alias *);#endif/* $NetBSD: cd.h,v 1.3 2002/11/24 22:35:39 christos Exp $ */static void setpwd(const char *, int);/* $NetBSD: error.h,v 1.15 2002/11/24 22:35:39 christos Exp $ *//* * Types of operations (passed to the errmsg routine). */static const char not_found_msg[] = "%s: not found";#define E_OPEN "No such file" /* opening a file */#define E_CREAT "Directory nonexistent" /* creating a file */#define E_EXEC not_found_msg+4 /* executing a program *//* * We enclose jmp_buf in a structure so that we can declare pointers to * jump locations. The global variable handler contains the location to * jump to when an exception occurs, and the global variable exception * contains a code identifying the exeception. To implement nested * exception handlers, the user should save the value of handler on entry * to an inner scope, set handler to point to a jmploc structure for the * inner scope, and restore handler on exit from the scope. */struct jmploc { jmp_buf loc;};static struct jmploc *handler;static int exception;static volatile int suppressint;static volatile sig_atomic_t intpending;static int exerrno; /* Last exec error, error for EXEXEC *//* exceptions */#define EXINT 0 /* SIGINT received */#define EXERROR 1 /* a generic error */#define EXSHELLPROC 2 /* execute a shell procedure */#define EXEXEC 3 /* command execution failed */#define EXEXIT 4 /* exit the shell */#define EXSIG 5 /* trapped signal in wait(1) *//* do we generate EXSIG events */static int exsig;/* last pending signal */static volatile sig_atomic_t pendingsigs;/* * These macros allow the user to suspend the handling of interrupt signals * over a period of time. This is similar to SIGHOLD to or sigblock, but * much more efficient and portable. (But hacking the kernel is so much * more fun than worrying about efficiency and portability. :-)) */#define barrier() ({ __asm__ __volatile__ ("": : :"memory"); })#define INTOFF \ ({ \ suppressint++; \ barrier(); \ 0; \ })#define SAVEINT(v) ((v) = suppressint)#define RESTOREINT(v) \ ({ \ barrier(); \ if ((suppressint = (v)) == 0 && intpending) onint(); \ 0; \ })#define EXSIGON() \ ({ \ exsig++; \ barrier(); \ if (pendingsigs) \ exraise(EXSIG); \ 0; \ })/* EXSIG is turned off by evalbltin(). */static void exraise(int) __attribute__((__noreturn__));static void onint(void) __attribute__((__noreturn__));static void error(const char *, ...) __attribute__((__noreturn__));static void exerror(int, const char *, ...) __attribute__((__noreturn__));static void sh_warnx(const char *, ...);#ifdef CONFIG_ASH_OPTIMIZE_FOR_SIZEstatic voidinton(void) { if (--suppressint == 0 && intpending) { onint(); }}#define INTON inton()static void forceinton(void){ suppressint = 0; if (intpending) onint();}#define FORCEINTON forceinton()#else#define INTON \ ({ \ barrier(); \ if (--suppressint == 0 && intpending) onint(); \ 0; \ })#define FORCEINTON \ ({ \ barrier(); \ suppressint = 0; \ if (intpending) onint(); \ 0; \ })#endif /* CONFIG_ASH_OPTIMIZE_FOR_SIZE *//* * BSD setjmp saves the signal mask, which violates ANSI C and takes time, * so we use _setjmp instead. */#if defined(BSD) && !defined(__SVR4) && !defined(__GLIBC__)#define setjmp(jmploc) _setjmp(jmploc)#define longjmp(jmploc, val) _longjmp(jmploc, val)#endif/* $NetBSD: expand.h,v 1.13 2002/11/24 22:35:40 christos Exp $ */struct strlist { struct strlist *next; char *text;};struct arglist { struct strlist *list; struct strlist **lastp;};/* * expandarg() flags */#define EXP_FULL 0x1 /* perform word splitting & file globbing */#define EXP_TILDE 0x2 /* do normal tilde expansion */#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */#define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */#define EXP_RECORD 0x20 /* need to record arguments for ifs breakup */#define EXP_VARTILDE2 0x40 /* expand tildes after colons only */#define EXP_WORD 0x80 /* expand word in parameter expansion */#define EXP_QWORD 0x100 /* expand word in quoted parameter expansion */union node;static void expandarg(union node *, struct arglist *, int);#define rmescapes(p) _rmescapes((p), 0)static char *_rmescapes(char *, int);static int casematch(union node *, char *);#ifdef CONFIG_ASH_MATH_SUPPORTstatic void expari(int);#endif/* $NetBSD: eval.h,v 1.13 2002/11/24 22:35:39 christos Exp $ */static char *commandname; /* currently executing command */static struct strlist *cmdenviron; /* environment for builtin command */static int exitstatus; /* exit status of last command */static int back_exitstatus; /* exit status of backquoted command */struct backcmd { /* result of evalbackcmd */ int fd; /* file descriptor to read from */ char *buf; /* buffer */ int nleft; /* number of chars in buffer */ struct job *jp; /* job structure for command */};/* * This file was generated by the mknodes program. */#define NCMD 0#define NPIPE 1#define NREDIR 2#define NBACKGND 3#define NSUBSHELL 4#define NAND 5#define NOR 6#define NSEMI 7#define NIF 8#define NWHILE 9#define NUNTIL 10#define NFOR 11#define NCASE 12#define NCLIST 13#define NDEFUN 14#define NARG 15#define NTO 16#define NCLOBBER 17#define NFROM 18#define NFROMTO 19#define NAPPEND 20#define NTOFD 21#define NFROMFD 22#define NHERE 23#define NXHERE 24#define NNOT 25struct ncmd { int type; union node *assign; union node *args; union node *redirect;};struct npipe { int type; int backgnd; struct nodelist *cmdlist;};struct nredir { int type; union node *n; union node *redirect;};struct nbinary { int type; union node *ch1; union node *ch2;};struct nif { int type; union node *test; union node *ifpart; union node *elsepart;};struct nfor { int type; union node *args; union node *body; char *var;};struct ncase { int type; union node *expr; union node *cases;};struct nclist { int type; union node *next; union node *pattern; union node *body;};struct narg { int type; union node *next; char *text; struct nodelist *backquote;};struct nfile { int type; union node *next; int fd; union node *fname; char *expfname;};struct ndup { int type; union node *next; int fd; int dupfd; union node *vname;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -