cb57d551a2
together by vodz, but uses newer sources, has the removed features commented out instead of simply deleted (so they could be re-enabled) and the builtins all work. This adds 72k. -Erik
1226 lines
31 KiB
C
1226 lines
31 KiB
C
/*-
|
|
* Copyright (c) 1993
|
|
* The Regents of the University of California. All rights reserved.
|
|
*
|
|
* This code is derived from software contributed to Berkeley by
|
|
* Kenneth Almquist.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by the University of
|
|
* California, Berkeley and its contributors.
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
/* $NetBSD: alias.h,v 1.4 1995/05/11 21:28:42 christos Exp $ */
|
|
|
|
#define ALIASINUSE 1
|
|
#define ALIASDEAD 2
|
|
|
|
struct alias {
|
|
struct alias *next;
|
|
char *name;
|
|
char *val;
|
|
int flag;
|
|
};
|
|
|
|
struct alias *lookupalias __P((const char *, int));
|
|
static int aliascmd __P((int, char **));
|
|
static int unaliascmd __P((int, char **));
|
|
static void rmaliases __P((void));
|
|
static int unalias __P((char *));
|
|
static void printalias __P((const struct alias *));
|
|
#define ARITH_NUM 257
|
|
#define ARITH_LPAREN 258
|
|
#define ARITH_RPAREN 259
|
|
#define ARITH_OR 260
|
|
#define ARITH_AND 261
|
|
#define ARITH_BOR 262
|
|
#define ARITH_BXOR 263
|
|
#define ARITH_BAND 264
|
|
#define ARITH_EQ 265
|
|
#define ARITH_NE 266
|
|
#define ARITH_LT 267
|
|
#define ARITH_GT 268
|
|
#define ARITH_GE 269
|
|
#define ARITH_LE 270
|
|
#define ARITH_LSHIFT 271
|
|
#define ARITH_RSHIFT 272
|
|
#define ARITH_ADD 273
|
|
#define ARITH_SUB 274
|
|
#define ARITH_MUL 275
|
|
#define ARITH_DIV 276
|
|
#define ARITH_REM 277
|
|
#define ARITH_UNARYMINUS 278
|
|
#define ARITH_UNARYPLUS 279
|
|
#define ARITH_NOT 280
|
|
#define ARITH_BNOT 281
|
|
|
|
/*
|
|
* This file was generated by the mkbuiltins program.
|
|
*/
|
|
|
|
|
|
#define BUILTIN_SPECIAL 0x1
|
|
#define BUILTIN_REGULAR 0x2
|
|
#define BUILTIN_ASSIGN 0x4
|
|
|
|
struct builtincmd {
|
|
const char *name;
|
|
int (*const builtinfunc) __P((int, char **));
|
|
unsigned flags;
|
|
};
|
|
|
|
extern const struct builtincmd builtincmds[];
|
|
|
|
|
|
|
|
/* $NetBSD: cd.h,v 1.2 1997/07/04 21:01:52 christos Exp $ */
|
|
static int cdcmd __P((int, char **));
|
|
static int pwdcmd __P((int, char **));
|
|
static void setpwd __P((const char *, int));
|
|
|
|
|
|
/* $NetBSD: error.h,v 1.14 2001/02/04 19:52:06 christos Exp $ */
|
|
|
|
/*
|
|
* Types of operations (passed to the errmsg routine).
|
|
*/
|
|
|
|
#define E_OPEN 01 /* opening a file */
|
|
#define E_CREAT 02 /* creating a file */
|
|
#define E_EXEC 04 /* 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;
|
|
};
|
|
|
|
extern struct jmploc *handler;
|
|
extern int exception;
|
|
|
|
/* 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 */
|
|
|
|
|
|
/*
|
|
* 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. :-))
|
|
*/
|
|
|
|
extern int suppressint;
|
|
extern volatile int intpending;
|
|
|
|
#define INTOFF suppressint++
|
|
#ifdef REALLY_SMALL
|
|
static void __inton __P((void));
|
|
#define INTON __inton()
|
|
#else
|
|
#define INTON { if (--suppressint == 0 && intpending) onint(); }
|
|
#endif
|
|
#define FORCEINTON {suppressint = 0; if (intpending) onint();}
|
|
#define CLEAR_PENDING_INT intpending = 0
|
|
#define int_pending() intpending
|
|
|
|
static void exraise __P((int)) __attribute__((__noreturn__));
|
|
static void onint __P((void));
|
|
static void error __P((const char *, ...)) __attribute__((__noreturn__));
|
|
static void exerror __P((int, const char *, ...)) __attribute__((__noreturn__));
|
|
static const char *errmsg __P((int, int));
|
|
|
|
|
|
/*
|
|
* 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: shell.h,v 1.13 2000/05/22 10:18:47 elric Exp $ */
|
|
|
|
/*
|
|
* The follow should be set to reflect the type of system you have:
|
|
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
|
|
* SHORTNAMES -> 1 if your linker cannot handle long names.
|
|
* define BSD if you are running 4.2 BSD or later.
|
|
* define SYSV if you are running under System V.
|
|
* define DEBUG=1 to compile in debugging (set global "debug" to turn on)
|
|
* define DEBUG=2 to compile in and turn on debugging.
|
|
*
|
|
* When debugging is on, debugging info will be written to $HOME/trace and
|
|
* a quit signal will generate a core dump.
|
|
*/
|
|
|
|
|
|
#define JOBS 1
|
|
#ifndef BSD
|
|
#define BSD 1
|
|
#endif
|
|
|
|
#ifdef __STDC__
|
|
typedef void *pointer;
|
|
#ifndef NULL
|
|
#define NULL (void *)0
|
|
#endif
|
|
#else /* not __STDC__ */
|
|
typedef char *pointer;
|
|
#ifndef NULL
|
|
#define NULL 0
|
|
#endif
|
|
#endif /* not __STDC__ */
|
|
|
|
extern char nullstr[1]; /* null string */
|
|
|
|
|
|
#ifdef DEBUG
|
|
#define TRACE(param) trace param
|
|
#else
|
|
#define TRACE(param)
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
* This file was generated by the mknodes program.
|
|
*/
|
|
|
|
#define NSEMI 0
|
|
#define NCMD 1
|
|
#define NPIPE 2
|
|
#define NREDIR 3
|
|
#define NBACKGND 4
|
|
#define NSUBSHELL 5
|
|
#define NAND 6
|
|
#define NOR 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 NFROM 17
|
|
#define NFROMTO 18
|
|
#define NAPPEND 19
|
|
#define NTOOV 20
|
|
#define NTOFD 21
|
|
#define NFROMFD 22
|
|
#define NHERE 23
|
|
#define NXHERE 24
|
|
#define NNOT 25
|
|
|
|
|
|
|
|
struct nbinary {
|
|
int type;
|
|
union node *ch1;
|
|
union node *ch2;
|
|
};
|
|
|
|
|
|
struct ncmd {
|
|
int type;
|
|
int backgnd;
|
|
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 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;
|
|
};
|
|
|
|
|
|
struct nhere {
|
|
int type;
|
|
union node *next;
|
|
int fd;
|
|
union node *doc;
|
|
};
|
|
|
|
|
|
struct nnot {
|
|
int type;
|
|
union node *com;
|
|
};
|
|
|
|
|
|
union node {
|
|
int type;
|
|
struct nbinary nbinary;
|
|
struct ncmd ncmd;
|
|
struct npipe npipe;
|
|
struct nredir nredir;
|
|
struct nif nif;
|
|
struct nfor nfor;
|
|
struct ncase ncase;
|
|
struct nclist nclist;
|
|
struct narg narg;
|
|
struct nfile nfile;
|
|
struct ndup ndup;
|
|
struct nhere nhere;
|
|
struct nnot nnot;
|
|
};
|
|
|
|
|
|
struct nodelist {
|
|
struct nodelist *next;
|
|
union node *n;
|
|
};
|
|
|
|
|
|
#ifdef __STDC__
|
|
union node *copyfunc(union node *);
|
|
static void freefunc(union node *);
|
|
#else
|
|
union node *copyfunc();
|
|
static void freefunc();
|
|
#endif
|
|
|
|
|
|
|
|
/* $NetBSD: eval.h,v 1.10 2000/01/27 23:39:40 christos Exp $ */
|
|
extern char *commandname; /* currently executing command */
|
|
extern int exitstatus; /* exit status of last command */
|
|
extern struct strlist *cmdenviron; /* environment for builtin 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 */
|
|
};
|
|
|
|
static int evalcmd __P((int, char **));
|
|
static void evalstring __P((char *, int));
|
|
static void evaltree __P((union node *, int));
|
|
static void evalbackcmd __P((union node *, struct backcmd *));
|
|
static int bltincmd __P((int, char **));
|
|
static int breakcmd __P((int, char **));
|
|
static int returncmd __P((int, char **));
|
|
static int execcmd __P((int, char **));
|
|
|
|
/* in_function returns nonzero if we are currently evaluating a function */
|
|
#define in_function() funcnest
|
|
extern int funcnest;
|
|
extern int evalskip;
|
|
|
|
/* reasons for skipping commands (see comment on breakcmd routine) */
|
|
#define SKIPBREAK 1
|
|
#define SKIPCONT 2
|
|
#define SKIPFUNC 3
|
|
#define SKIPFILE 4
|
|
|
|
|
|
|
|
|
|
/* $NetBSD: exec.h,v 1.17 2000/05/22 10:18:47 elric Exp $ */
|
|
|
|
/* values of cmdtype */
|
|
#define CMDUNKNOWN -1 /* no entry in table for command */
|
|
#define CMDNORMAL 0 /* command is an executable program */
|
|
#define CMDBUILTIN 1 /* command is a shell builtin */
|
|
#define CMDFUNCTION 2 /* command is a shell function */
|
|
|
|
|
|
struct cmdentry {
|
|
int cmdtype;
|
|
union param {
|
|
int index;
|
|
union node *func;
|
|
const struct builtincmd *cmd;
|
|
} u;
|
|
};
|
|
|
|
|
|
#define DO_ERR 1 /* find_command prints errors */
|
|
#define DO_ABS 2 /* find_command checks absolute paths */
|
|
#define DO_NOFUN 4 /* find_command ignores functions */
|
|
#define DO_BRUTE 8 /* find_command ignores hash table */
|
|
|
|
extern const char *pathopt; /* set by padvance */
|
|
extern int exerrno; /* last exec error */
|
|
|
|
static void shellexec __P((char **, char **, const char *, int))
|
|
__attribute__((noreturn));
|
|
static char *padvance __P((const char **, const char *));
|
|
static int hashcmd __P((int, char **));
|
|
static void find_command __P((char *, struct cmdentry *, int, const char *));
|
|
struct builtincmd *find_builtin __P((char *));
|
|
static void hashcd __P((void));
|
|
static void changepath __P((const char *));
|
|
static void deletefuncs __P((void));
|
|
#ifdef notdef
|
|
static void getcmdentry __P((char *, struct cmdentry *));
|
|
#endif
|
|
static void addcmdentry __P((char *, struct cmdentry *));
|
|
static void defun __P((char *, union node *));
|
|
static void unsetfunc __P((char *));
|
|
#ifdef ASH_TYPE
|
|
static int typecmd __P((int, char **));
|
|
#endif
|
|
static int commandcmd __P((int, char **));
|
|
|
|
|
|
|
|
/* $NetBSD: expand.h,v 1.12 1999/07/09 03:05:50 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 */
|
|
|
|
|
|
static void expandhere __P((union node *, int));
|
|
static void expandarg __P((union node *, struct arglist *, int));
|
|
#ifdef ASH_MATH_SUPPORT
|
|
static void expari __P((int));
|
|
#endif
|
|
#if !(defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
|
|
static int patmatch __P((char *, char *, int));
|
|
#endif
|
|
#if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
|
|
#define rmescapes(p) _rmescapes((p), 0)
|
|
static char *_rmescapes __P((char *, int));
|
|
#else
|
|
static void rmescapes __P((char *));
|
|
#endif
|
|
static int casematch __P((union node *, char *));
|
|
|
|
|
|
#ifdef ASH_MATH_SUPPORT
|
|
/* From arith.y */
|
|
static int arith __P((const char *));
|
|
static int expcmd __P((int , char **));
|
|
static void arith_lex_reset __P((void));
|
|
static int yylex __P((void));
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* $NetBSD: init.h,v 1.8 1995/05/11 21:29:14 christos Exp $ */
|
|
static void init __P((void));
|
|
static void reset __P((void));
|
|
static void initshellproc __P((void));
|
|
|
|
|
|
|
|
/* $NetBSD: input.h,v 1.12 2000/05/22 10:18:47 elric Exp $ */
|
|
|
|
/* PEOF (the end of file marker) is defined in syntax.h */
|
|
/*
|
|
* The input line number. Input.c just defines this variable, and saves
|
|
* and restores it when files are pushed and popped. The user of this
|
|
* package must set its value.
|
|
*/
|
|
extern int plinno;
|
|
extern int parsenleft; /* number of characters left in input buffer */
|
|
extern char *parsenextc; /* next character in input buffer */
|
|
|
|
static char *pfgets __P((char *, int));
|
|
static int pgetc __P((void));
|
|
static int pgetc2 __P((void));
|
|
static int preadbuffer __P((void));
|
|
static void pungetc __P((void));
|
|
static void pushstring __P((char *, int, void *));
|
|
static void popstring __P((void));
|
|
static void setinputfile __P((const char *, int));
|
|
static void setinputfd __P((int, int));
|
|
static void setinputstring __P((char *));
|
|
static void popfile __P((void));
|
|
static void popallfiles __P((void));
|
|
static void closescript __P((void));
|
|
|
|
#define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
|
|
|
|
|
|
|
|
/* $NetBSD: jobs.h,v 1.12 2000/05/22 10:18:47 elric Exp $ */
|
|
|
|
/* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
|
|
#define FORK_FG 0
|
|
#define FORK_BG 1
|
|
#define FORK_NOJOB 2
|
|
|
|
|
|
/*
|
|
* A job structure contains information about a job. A job is either a
|
|
* single process or a set of processes contained in a pipeline. In the
|
|
* latter case, pidlist will be non-NULL, and will point to a -1 terminated
|
|
* array of pids.
|
|
*/
|
|
|
|
struct procstat {
|
|
pid_t pid; /* process id */
|
|
int status; /* status flags (defined above) */
|
|
char *cmd; /* text of command being run */
|
|
};
|
|
|
|
|
|
/* states */
|
|
#define JOBSTOPPED 1 /* all procs are stopped */
|
|
#define JOBDONE 2 /* all procs are completed */
|
|
|
|
|
|
struct job {
|
|
struct procstat ps0; /* status of process */
|
|
struct procstat *ps; /* status or processes when more than one */
|
|
short nprocs; /* number of processes */
|
|
short pgrp; /* process group of this job */
|
|
char state; /* true if job is finished */
|
|
char used; /* true if this entry is in used */
|
|
char changed; /* true if status has changed */
|
|
#if JOBS
|
|
char jobctl; /* job running under job control */
|
|
#endif
|
|
};
|
|
|
|
extern short backgndpid; /* pid of last background process */
|
|
extern int job_warning; /* user was warned about stopped jobs */
|
|
|
|
static void setjobctl __P((int));
|
|
static int killcmd __P((int, char **));
|
|
static int fgcmd __P((int, char **));
|
|
static int bgcmd __P((int, char **));
|
|
static int jobscmd __P((int, char **));
|
|
static void showjobs __P((int));
|
|
static int waitcmd __P((int, char **));
|
|
struct job *makejob __P((union node *, int));
|
|
static int forkshell __P((struct job *, union node *, int));
|
|
static int waitforjob __P((struct job *));
|
|
static int stoppedjobs __P((void));
|
|
static char *commandtext __P((union node *));
|
|
|
|
#if ! JOBS
|
|
#define setjobctl(on) /* do nothing */
|
|
#endif
|
|
|
|
|
|
|
|
/* $NetBSD: machdep.h,v 1.8 1995/05/11 21:29:21 christos Exp $ */
|
|
|
|
/*
|
|
* Most machines require the value returned from malloc to be aligned
|
|
* in some way. The following macro will get this right on many machines.
|
|
*/
|
|
|
|
#ifndef ALIGN
|
|
union align {
|
|
int i;
|
|
char *cp;
|
|
};
|
|
|
|
#define ALIGN(nbytes) (((nbytes) + sizeof(union align) - 1) & ~(sizeof(union align) - 1))
|
|
#endif
|
|
|
|
|
|
|
|
/* $NetBSD: mail.h,v 1.8 1995/05/11 21:29:23 christos Exp $ */
|
|
|
|
static void chkmail __P((int));
|
|
|
|
|
|
|
|
/* $NetBSD: main.h,v 1.8 1995/05/11 21:29:27 christos Exp $ */
|
|
extern int rootpid; /* pid of main shell */
|
|
extern int rootshell; /* true if we aren't a child of the main shell */
|
|
|
|
static void readcmdfile __P((char *));
|
|
static void cmdloop __P((int));
|
|
static int dotcmd __P((int, char **));
|
|
static int exitcmd __P((int, char **));
|
|
|
|
|
|
|
|
/* $NetBSD: memalloc.h,v 1.11 2000/11/01 19:56:01 christos Exp $ */
|
|
struct stackmark {
|
|
struct stack_block *stackp;
|
|
char *stacknxt;
|
|
int stacknleft;
|
|
struct stackmark *marknext;
|
|
};
|
|
|
|
|
|
extern char *stacknxt;
|
|
extern int stacknleft;
|
|
extern int sstrnleft;
|
|
extern int herefd;
|
|
|
|
static inline pointer ckmalloc (int sz) { return xmalloc(sz); }
|
|
static inline pointer ckrealloc(void *p, int sz) { return xrealloc(p, sz); }
|
|
static inline char * savestr (const char *s) { return xstrdup(s); }
|
|
|
|
pointer stalloc __P((int));
|
|
static void stunalloc __P((pointer));
|
|
static void setstackmark __P((struct stackmark *));
|
|
static void popstackmark __P((struct stackmark *));
|
|
static void growstackblock __P((void));
|
|
static void grabstackblock __P((int));
|
|
static char *growstackstr __P((void));
|
|
static char *makestrspace __P((size_t));
|
|
static void ungrabstackstr __P((char *, char *));
|
|
|
|
|
|
|
|
#define stackblock() stacknxt
|
|
#define stackblocksize() stacknleft
|
|
#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
|
|
#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
|
|
#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(n); }
|
|
#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
|
|
#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
|
|
#define STUNPUTC(p) (++sstrnleft, --p)
|
|
#define STTOPC(p) p[-1]
|
|
#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount))
|
|
#define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
|
|
|
|
#define ckfree(p) free((pointer)(p))
|
|
|
|
|
|
|
|
/* $NetBSD: miscbltin.h,v 1.1 1997/07/04 21:02:10 christos Exp $ */
|
|
static int readcmd __P((int, char **));
|
|
static int umaskcmd __P((int, char **));
|
|
static int ulimitcmd __P((int, char **));
|
|
|
|
|
|
|
|
/* $NetBSD: mystring.h,v 1.9 1995/05/11 21:29:42 christos Exp $ */
|
|
|
|
extern const char snlfmt[];
|
|
extern const char spcstr[];
|
|
|
|
#if 0
|
|
static void scopyn __P((const char *, char *, int));
|
|
#endif
|
|
static int prefix __P((const char *, const char *));
|
|
static int number __P((const char *));
|
|
static int is_number __P((const char *));
|
|
static char *single_quote __P((const char *));
|
|
static char *sstrdup __P((const char *));
|
|
static int pstrcmp __P((const void *, const void *));
|
|
static const char *const *findstring __P((const char *, const char *const *, size_t));
|
|
|
|
#define equal(s1, s2) (strcmp(s1, s2) == 0)
|
|
#define scopy(s1, s2) ((void)strcpy(s2, s1))
|
|
|
|
|
|
/* $NetBSD: options.h,v 1.14 2001/02/04 19:52:06 christos Exp $ */
|
|
|
|
struct shparam {
|
|
int nparam; /* # of positional parameters (without $0) */
|
|
unsigned char malloc; /* if parameter list dynamically allocated */
|
|
char **p; /* parameter list */
|
|
int optind; /* next parameter to be processed by getopts */
|
|
int optoff; /* used by getopts */
|
|
};
|
|
|
|
|
|
|
|
#define eflag optlist[0].val
|
|
#define fflag optlist[1].val
|
|
#define Iflag optlist[2].val
|
|
#define iflag optlist[3].val
|
|
#define mflag optlist[4].val
|
|
#define nflag optlist[5].val
|
|
#define sflag optlist[6].val
|
|
#define xflag optlist[7].val
|
|
#define vflag optlist[8].val
|
|
#define Vflag optlist[9].val
|
|
#define Eflag optlist[10].val
|
|
#define Cflag optlist[11].val
|
|
#define aflag optlist[12].val
|
|
#define bflag optlist[13].val
|
|
#define uflag optlist[14].val
|
|
#define qflag optlist[15].val
|
|
|
|
#define NOPTS 16
|
|
|
|
struct optent {
|
|
const char *name;
|
|
const char letter;
|
|
char val;
|
|
};
|
|
|
|
extern struct optent optlist[NOPTS];
|
|
|
|
|
|
extern char *minusc; /* argument to -c option */
|
|
extern char *arg0; /* $0 */
|
|
extern struct shparam shellparam; /* $@ */
|
|
extern char **argptr; /* argument list for builtin commands */
|
|
extern char *optionarg; /* set by nextopt */
|
|
extern char *optptr; /* used by nextopt */
|
|
|
|
static void procargs __P((int, char **));
|
|
static void optschanged __P((void));
|
|
static void setparam __P((char **));
|
|
static void freeparam __P((volatile struct shparam *));
|
|
static int shiftcmd __P((int, char **));
|
|
static int setcmd __P((int, char **));
|
|
#ifdef ASH_GETOPTS
|
|
static int getoptscmd __P((int, char **));
|
|
static int setvarsafe __P((const char *, const char *, int));
|
|
#endif
|
|
static int nextopt __P((const char *));
|
|
static void getoptsreset __P((const char *));
|
|
|
|
|
|
|
|
/* $NetBSD: output.h,v 1.14 1998/01/31 12:37:55 christos Exp $ */
|
|
struct output {
|
|
#ifdef USE_GLIBC_STDIO
|
|
FILE *stream;
|
|
#endif
|
|
char *nextc;
|
|
int nleft;
|
|
char *buf;
|
|
int bufsize;
|
|
int fd;
|
|
short flags;
|
|
};
|
|
|
|
extern struct output output;
|
|
extern struct output errout;
|
|
extern struct output memout;
|
|
extern struct output *out1;
|
|
extern struct output *out2;
|
|
|
|
static void outstr __P((const char *, struct output *));
|
|
#ifndef USE_GLIBC_STDIO
|
|
static void outcslow __P((char, struct output *));
|
|
#endif
|
|
static void flushall __P((void));
|
|
static void flushout __P((struct output *));
|
|
static void freestdout __P((void));
|
|
static void outfmt __P((struct output *, const char *, ...))
|
|
__attribute__((__format__(__printf__,2,3)));
|
|
static void out1fmt __P((const char *, ...))
|
|
__attribute__((__format__(__printf__,1,2)));
|
|
static void fmtstr __P((char *, size_t, const char *, ...))
|
|
__attribute__((__format__(__printf__,3,4)));
|
|
#ifndef USE_GLIBC_STDIO
|
|
static void doformat __P((struct output *, const char *, va_list));
|
|
#endif
|
|
static int xwrite __P((int, const char *, int));
|
|
#ifdef USE_GLIBC_STDIO
|
|
static void initstreams __P((void));
|
|
static void openmemout __P((void));
|
|
static int __closememout __P((void));
|
|
#endif
|
|
|
|
#define OUTPUT_ERR 01 /* error occurred on output */
|
|
|
|
#ifdef USE_GLIBC_STDIO
|
|
#define outc(c, o) putc((c), (o)->stream)
|
|
#define doformat(d, f, a) vfprintf((d)->stream, (f), (a))
|
|
#else
|
|
#define outc(c, file) (--(file)->nleft < 0? outcslow((c), (file)) : (*(file)->nextc = (c), (file)->nextc++))
|
|
#endif
|
|
#define out1c(c) outc((c), out1)
|
|
#define out2c(c) outc((c), out2)
|
|
#define out1str(s) outstr((s), out1)
|
|
#define out2str(s) outstr((s), out2)
|
|
#define outerr(f) ((f)->flags & OUTPUT_ERR)
|
|
|
|
|
|
|
|
/* $NetBSD: parser.h,v 1.14 2000/07/27 04:09:28 cgd Exp $ */
|
|
/* control characters in argument strings */
|
|
#define CTLESC '\201'
|
|
#define CTLVAR '\202'
|
|
#define CTLENDVAR '\203'
|
|
#define CTLBACKQ '\204'
|
|
#define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
|
|
/* CTLBACKQ | CTLQUOTE == '\205' */
|
|
#define CTLARI '\206'
|
|
#define CTLENDARI '\207'
|
|
#define CTLQUOTEMARK '\210'
|
|
|
|
/* variable substitution byte (follows CTLVAR) */
|
|
#define VSTYPE 0x0f /* type of variable substitution */
|
|
#define VSNUL 0x10 /* colon--treat the empty string as unset */
|
|
#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
|
|
|
|
/* values of VSTYPE field */
|
|
#define VSNORMAL 0x1 /* normal variable: $var or ${var} */
|
|
#define VSMINUS 0x2 /* ${var-text} */
|
|
#define VSPLUS 0x3 /* ${var+text} */
|
|
#define VSQUESTION 0x4 /* ${var?message} */
|
|
#define VSASSIGN 0x5 /* ${var=text} */
|
|
#define VSTRIMLEFT 0x6 /* ${var#pattern} */
|
|
#define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */
|
|
#define VSTRIMRIGHT 0x8 /* ${var%pattern} */
|
|
#define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */
|
|
#define VSLENGTH 0xa /* ${#var} */
|
|
|
|
|
|
/*
|
|
* NEOF is returned by parsecmd when it encounters an end of file. It
|
|
* must be distinct from NULL, so we use the address of a variable that
|
|
* happens to be handy.
|
|
*/
|
|
extern int tokpushback;
|
|
#define NEOF ((union node *)&tokpushback)
|
|
extern int whichprompt; /* 1 == PS1, 2 == PS2 */
|
|
extern int checkalias;
|
|
|
|
|
|
union node *parsecmd(int);
|
|
static void fixredir(union node *, const char *, int);
|
|
static int goodname(char *);
|
|
static const char *getprompt(void *);
|
|
static int isassignment __P((const char *));
|
|
static const char *const *findkwd __P((const char *));
|
|
|
|
|
|
/* $NetBSD: redir.h,v 1.12 2000/05/22 10:18:47 elric Exp $ */
|
|
/* flags passed to redirect */
|
|
#define REDIR_PUSH 01 /* save previous values of file descriptors */
|
|
#define REDIR_BACKQ 02 /* save the command output in memory */
|
|
|
|
extern int fileno2;
|
|
|
|
static void redirect __P((union node *, int));
|
|
static void popredir __P((void));
|
|
static int fd0_redirected_p __P((void));
|
|
static void clearredir __P((void));
|
|
static int dup_as_newfd __P((int, int));
|
|
|
|
|
|
|
|
|
|
/* $NetBSD: show.h,v 1.4 1999/10/08 21:10:44 pk Exp $ */
|
|
#ifdef DEBUG
|
|
static void trace __P((const char *, ...));
|
|
static void trargs __P((char **));
|
|
static void showtree __P((union node *));
|
|
static void trputc __P((int));
|
|
static void trputs __P((const char *));
|
|
static void opentrace __P((void));
|
|
#endif
|
|
/*
|
|
* This file was generated by the mksyntax program.
|
|
*/
|
|
|
|
#ifdef CEOF
|
|
#undef CEOF
|
|
#endif
|
|
|
|
/* Syntax classes */
|
|
#define CWORD 0 /* character is nothing special */
|
|
#define CNL 1 /* newline character */
|
|
#define CBACK 2 /* a backslash character */
|
|
#define CSQUOTE 3 /* single quote */
|
|
#define CDQUOTE 4 /* double quote */
|
|
#define CENDQUOTE 5 /* a terminating quote */
|
|
#define CBQUOTE 6 /* backwards single quote */
|
|
#define CVAR 7 /* a dollar sign */
|
|
#define CENDVAR 8 /* a '}' character */
|
|
#define CLP 9 /* a left paren in arithmetic */
|
|
#define CRP 10 /* a right paren in arithmetic */
|
|
#define CEOF 11 /* end of file */
|
|
#define CCTL 12 /* like CWORD, except it must be escaped */
|
|
#define CSPCL 13 /* these terminate a word */
|
|
#define CIGN 14 /* character should be ignored */
|
|
|
|
/* Syntax classes for is_ functions */
|
|
#define ISDIGIT 01 /* a digit */
|
|
#define ISUPPER 02 /* an upper case letter */
|
|
#define ISLOWER 04 /* a lower case letter */
|
|
#define ISUNDER 010 /* an underscore */
|
|
#define ISSPECL 020 /* the name of a special parameter */
|
|
|
|
#define SYNBASE 130
|
|
#define PEOF -130
|
|
|
|
#define PEOA -129
|
|
|
|
|
|
#define BASESYNTAX (basesyntax + SYNBASE)
|
|
#define DQSYNTAX (dqsyntax + SYNBASE)
|
|
#define SQSYNTAX (sqsyntax + SYNBASE)
|
|
#define ARISYNTAX (arisyntax + SYNBASE)
|
|
|
|
#define is_digit(c) ((unsigned)((c) - '0') <= 9)
|
|
#define is_alpha(c) (((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c)))
|
|
#define is_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c))))
|
|
#define is_in_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c))))
|
|
#define is_special(c) ((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))
|
|
#define digit_val(c) ((c) - '0')
|
|
|
|
extern const char basesyntax[];
|
|
extern const char dqsyntax[];
|
|
extern const char sqsyntax[];
|
|
extern const char arisyntax[];
|
|
extern const char is_type[];
|
|
#define TEOF 0
|
|
#define TNL 1
|
|
#define TSEMI 2
|
|
#define TBACKGND 3
|
|
#define TAND 4
|
|
#define TOR 5
|
|
#define TPIPE 6
|
|
#define TLP 7
|
|
#define TRP 8
|
|
#define TENDCASE 9
|
|
#define TENDBQUOTE 10
|
|
#define TREDIR 11
|
|
#define TWORD 12
|
|
#define TASSIGN 13
|
|
#define TNOT 14
|
|
#define TCASE 15
|
|
#define TDO 16
|
|
#define TDONE 17
|
|
#define TELIF 18
|
|
#define TELSE 19
|
|
#define TESAC 20
|
|
#define TFI 21
|
|
#define TFOR 22
|
|
#define TIF 23
|
|
#define TIN 24
|
|
#define TTHEN 25
|
|
#define TUNTIL 26
|
|
#define TWHILE 27
|
|
#define TBEGIN 28
|
|
#define TEND 29
|
|
|
|
/* Array indicating which tokens mark the end of a list */
|
|
static const char tokendlist[] = {
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
1,
|
|
1,
|
|
1,
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
1,
|
|
};
|
|
|
|
static const char *const tokname[] = {
|
|
"end of file",
|
|
"newline",
|
|
"\";\"",
|
|
"\"&\"",
|
|
"\"&&\"",
|
|
"\"||\"",
|
|
"\"|\"",
|
|
"\"(\"",
|
|
"\")\"",
|
|
"\";;\"",
|
|
"\"`\"",
|
|
"redirection",
|
|
"word",
|
|
"assignment",
|
|
"\"!\"",
|
|
"\"case\"",
|
|
"\"do\"",
|
|
"\"done\"",
|
|
"\"elif\"",
|
|
"\"else\"",
|
|
"\"esac\"",
|
|
"\"fi\"",
|
|
"\"for\"",
|
|
"\"if\"",
|
|
"\"in\"",
|
|
"\"then\"",
|
|
"\"until\"",
|
|
"\"while\"",
|
|
"\"{\"",
|
|
"\"}\"",
|
|
};
|
|
|
|
#define KWDOFFSET 14
|
|
|
|
static const char *const parsekwd[] = {
|
|
"!",
|
|
"case",
|
|
"do",
|
|
"done",
|
|
"elif",
|
|
"else",
|
|
"esac",
|
|
"fi",
|
|
"for",
|
|
"if",
|
|
"in",
|
|
"then",
|
|
"until",
|
|
"while",
|
|
"{",
|
|
"}"
|
|
};
|
|
|
|
|
|
|
|
|
|
/* $NetBSD: trap.h,v 1.14 2000/05/22 10:18:47 elric Exp $ */
|
|
extern int pendingsigs;
|
|
|
|
static int trapcmd __P((int, char **));
|
|
static void clear_traps __P((void));
|
|
static void setsignal __P((int));
|
|
static void ignoresig __P((int));
|
|
static void onsig __P((int));
|
|
static void dotrap __P((void));
|
|
static void setinteractive __P((int));
|
|
static void exitshell __P((int)) __attribute__((noreturn));
|
|
static int decode_signal __P((const char *, int));
|
|
|
|
|
|
|
|
/* $NetBSD: var.h,v 1.18 2000/05/22 10:18:47 elric Exp $ */
|
|
|
|
/*
|
|
* Shell variables.
|
|
*/
|
|
|
|
/* flags */
|
|
#define VEXPORT 0x01 /* variable is exported */
|
|
#define VREADONLY 0x02 /* variable cannot be modified */
|
|
#define VSTRFIXED 0x04 /* variable struct is staticly allocated */
|
|
#define VTEXTFIXED 0x08 /* text is staticly allocated */
|
|
#define VSTACK 0x10 /* text is allocated on the stack */
|
|
#define VUNSET 0x20 /* the variable is not set */
|
|
#define VNOFUNC 0x40 /* don't call the callback function */
|
|
|
|
|
|
struct var {
|
|
struct var *next; /* next entry in hash list */
|
|
int flags; /* flags are defined above */
|
|
char *text; /* name=value */
|
|
void (*func) __P((const char *));
|
|
/* function to be called when */
|
|
/* the variable gets set/unset */
|
|
};
|
|
|
|
|
|
struct localvar {
|
|
struct localvar *next; /* next local variable in list */
|
|
struct var *vp; /* the variable that was made local */
|
|
int flags; /* saved flags */
|
|
char *text; /* saved text */
|
|
};
|
|
|
|
|
|
extern struct localvar *localvars;
|
|
|
|
#if ATTY
|
|
extern struct var vatty;
|
|
#endif
|
|
extern struct var vifs;
|
|
extern struct var vmail;
|
|
extern struct var vmpath;
|
|
extern struct var vpath;
|
|
extern struct var vps1;
|
|
extern struct var vps2;
|
|
#ifndef SMALL
|
|
extern struct var vterm;
|
|
extern struct var vtermcap;
|
|
extern struct var vhistsize;
|
|
#endif
|
|
|
|
#ifdef IFS_BROKEN
|
|
extern const char defifsvar[];
|
|
#define defifs (defifsvar + 4)
|
|
#else
|
|
extern const char defifs[];
|
|
#endif
|
|
extern const char defpathvar[];
|
|
#define defpath (defpathvar + 5)
|
|
|
|
/*
|
|
* The following macros access the values of the above variables.
|
|
* They have to skip over the name. They return the null string
|
|
* for unset variables.
|
|
*/
|
|
|
|
#define ifsval() (vifs.text + 4)
|
|
#define ifsset() ((vifs.flags & VUNSET) == 0)
|
|
#define mailval() (vmail.text + 5)
|
|
#define mpathval() (vmpath.text + 9)
|
|
#define pathval() (vpath.text + 5)
|
|
#define ps1val() (vps1.text + 4)
|
|
#define ps2val() (vps2.text + 4)
|
|
#define optindval() (voptind.text + 7)
|
|
#ifndef SMALL
|
|
#define histsizeval() (vhistsize.text + 9)
|
|
#define termval() (vterm.text + 5)
|
|
#endif
|
|
|
|
#if ATTY
|
|
#define attyset() ((vatty.flags & VUNSET) == 0)
|
|
#endif
|
|
#define mpathset() ((vmpath.flags & VUNSET) == 0)
|
|
|
|
static void initvar __P((void));
|
|
static void setvar __P((const char *, const char *, int));
|
|
static void setvareq __P((char *, int));
|
|
struct strlist;
|
|
static void listsetvar __P((struct strlist *));
|
|
static char *lookupvar __P((const char *));
|
|
static char *bltinlookup __P((const char *));
|
|
static char **environment __P((void));
|
|
static void shprocvar __P((void));
|
|
static int showvarscmd __P((int, char **));
|
|
static int exportcmd __P((int, char **));
|
|
static int localcmd __P((int, char **));
|
|
static void mklocal __P((char *));
|
|
static void poplocalvars __P((void));
|
|
static int setvarcmd __P((int, char **));
|
|
static int unsetcmd __P((int, char **));
|
|
static int unsetvar __P((const char *));
|
|
static int varequal __P((const char *, const char *));
|
|
|