aboutsummaryrefslogtreecommitdiff
path: root/bin/ksh/sh.h
diff options
context:
space:
mode:
Diffstat (limited to 'bin/ksh/sh.h')
-rw-r--r--bin/ksh/sh.h608
1 files changed, 608 insertions, 0 deletions
diff --git a/bin/ksh/sh.h b/bin/ksh/sh.h
new file mode 100644
index 0000000..16f609d
--- /dev/null
+++ b/bin/ksh/sh.h
@@ -0,0 +1,608 @@
+/* $OpenBSD: sh.h,v 1.57 2016/03/04 15:11:06 deraadt Exp $ */
+
+/*
+ * Public Domain Bourne/Korn shell
+ */
+
+/* $From: sh.h,v 1.2 1994/05/19 18:32:40 michael Exp michael $ */
+
+#include "config.h" /* system and option configuration info */
+
+/* Start of common headers */
+
+#include <setjmp.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <stdbool.h>
+
+/* end of common headers */
+
+#define NELEM(a) (sizeof(a) / sizeof((a)[0]))
+#define BIT(i) (1<<(i)) /* define bit in flag */
+
+#define NUFILE 32 /* Number of user-accessible files */
+#define FDBASE 10 /* First file usable by Shell */
+
+#define BITS(t) (CHAR_BIT * sizeof(t))
+
+/* Make MAGIC a char that might be printed to make bugs more obvious, but
+ * not a char that is used often. Also, can't use the high bit as it causes
+ * portability problems (calling strchr(x, 0x80|'x') is error prone).
+ */
+#define MAGIC (7) /* prefix for *?[!{,} during expand */
+#define ISMAGIC(c) ((unsigned char)(c) == MAGIC)
+
+#define LINE 2048 /* input line size */
+#define PATH 1024 /* pathname size (todo: PATH_MAX/pathconf()) */
+
+extern const char *kshname; /* $0 */
+extern pid_t kshpid; /* $$, shell pid */
+extern pid_t procpid; /* pid of executing process */
+extern uid_t ksheuid; /* effective uid of shell */
+extern int exstat; /* exit status */
+extern int subst_exstat; /* exit status of last $(..)/`..` */
+extern const char *safe_prompt; /* safe prompt if PS1 substitution fails */
+extern char username[]; /* username for \u prompt expansion */
+
+/*
+ * Area-based allocation built on malloc/free
+ */
+typedef struct Area {
+ struct link *freelist; /* free list */
+} Area;
+
+extern Area aperm; /* permanent object space */
+#define APERM &aperm
+#define ATEMP &genv->area
+
+#ifdef KSH_DEBUG
+# define kshdebug_init() kshdebug_init_()
+# define kshdebug_printf(a) kshdebug_printf_ a
+# define kshdebug_dump(a) kshdebug_dump_ a
+#else /* KSH_DEBUG */
+# define kshdebug_init()
+# define kshdebug_printf(a)
+# define kshdebug_dump(a)
+#endif /* KSH_DEBUG */
+
+/*
+ * parsing & execution environment
+ */
+struct env {
+ short type; /* environment type - see below */
+ short flags; /* EF_* */
+ Area area; /* temporary allocation area */
+ struct block *loc; /* local variables and functions */
+ short *savefd; /* original redirected fd's */
+ struct env *oenv; /* link to previous environment */
+ sigjmp_buf jbuf; /* long jump back to env creator */
+ struct temp *temps; /* temp files */
+};
+extern struct env *genv;
+
+/* struct env.type values */
+#define E_NONE 0 /* dummy environment */
+#define E_PARSE 1 /* parsing command # */
+#define E_FUNC 2 /* executing function # */
+#define E_INCL 3 /* including a file via . # */
+#define E_EXEC 4 /* executing command tree */
+#define E_LOOP 5 /* executing for/while # */
+#define E_ERRH 6 /* general error handler # */
+/* # indicates env has valid jbuf (see unwind()) */
+
+/* struct env.flag values */
+#define EF_FUNC_PARSE BIT(0) /* function being parsed */
+#define EF_BRKCONT_PASS BIT(1) /* set if E_LOOP must pass break/continue on */
+#define EF_FAKE_SIGDIE BIT(2) /* hack to get info from unwind to quitenv */
+
+/* Do breaks/continues stop at env type e? */
+#define STOP_BRKCONT(t) ((t) == E_NONE || (t) == E_PARSE \
+ || (t) == E_FUNC || (t) == E_INCL)
+/* Do returns stop at env type e? */
+#define STOP_RETURN(t) ((t) == E_FUNC || (t) == E_INCL)
+
+/* values for siglongjmp(e->jbuf, 0) */
+#define LRETURN 1 /* return statement */
+#define LEXIT 2 /* exit statement */
+#define LERROR 3 /* errorf() called */
+#define LLEAVE 4 /* untrappable exit/error */
+#define LINTR 5 /* ^C noticed */
+#define LBREAK 6 /* break statement */
+#define LCONTIN 7 /* continue statement */
+#define LSHELL 8 /* return to interactive shell() */
+#define LAEXPR 9 /* error in arithmetic expression */
+
+/* option processing */
+#define OF_CMDLINE 0x01 /* command line */
+#define OF_SET 0x02 /* set builtin */
+#define OF_SPECIAL 0x04 /* a special variable changing */
+#define OF_INTERNAL 0x08 /* set internally by shell */
+#define OF_ANY (OF_CMDLINE | OF_SET | OF_SPECIAL | OF_INTERNAL)
+
+struct option {
+ const char *name; /* long name of option */
+ char c; /* character flag (if any) */
+ short flags; /* OF_* */
+};
+extern const struct option options[];
+
+/*
+ * flags (the order of these enums MUST match the order in misc.c(options[]))
+ */
+enum sh_flag {
+ FEXPORT = 0, /* -a: export all */
+#ifdef BRACE_EXPAND
+ FBRACEEXPAND, /* enable {} globbing */
+#endif
+ FBGNICE, /* bgnice */
+ FCOMMAND, /* -c: (invocation) execute specified command */
+ FCSHHISTORY, /* csh-style history enabled */
+#ifdef EMACS
+ FEMACS, /* emacs command editing */
+ FEMACSUSEMETA, /* use 8th bit as meta */
+#endif
+ FERREXIT, /* -e: quit on error */
+#ifdef EMACS
+ FGMACS, /* gmacs command editing */
+#endif
+ FIGNOREEOF, /* eof does not exit */
+ FTALKING, /* -i: interactive */
+ FKEYWORD, /* -k: name=value anywhere */
+ FLOGIN, /* -l: a login shell */
+ FMARKDIRS, /* mark dirs with / in file name completion */
+ FMONITOR, /* -m: job control monitoring */
+ FNOCLOBBER, /* -C: don't overwrite existing files */
+ FNOEXEC, /* -n: don't execute any commands */
+ FNOGLOB, /* -f: don't do file globbing */
+ FNOHUP, /* -H: don't kill running jobs when login shell exits */
+ FNOLOG, /* don't save functions in history (ignored) */
+#ifdef JOBS
+ FNOTIFY, /* -b: asynchronous job completion notification */
+#endif
+ FNOUNSET, /* -u: using an unset var is an error */
+ FPHYSICAL, /* -o physical: don't do logical cd's/pwd's */
+ FPOSIX, /* -o posix: be posixly correct */
+ FPRIVILEGED, /* -p: use suid_profile */
+ FRESTRICTED, /* -r: restricted shell */
+ FSH, /* -o sh: favor sh behaviour */
+ FSTDIN, /* -s: (invocation) parse stdin */
+ FTRACKALL, /* -h: create tracked aliases for all commands */
+ FVERBOSE, /* -v: echo input */
+#ifdef VI
+ FVI, /* vi command editing */
+ FVIRAW, /* always read in raw mode (ignored) */
+ FVISHOW8, /* display chars with 8th bit set as is (versus M-) */
+ FVITABCOMPLETE, /* enable tab as file name completion char */
+ FVIESCCOMPLETE, /* enable ESC as file name completion in command mode */
+#endif
+ FXTRACE, /* -x: execution trace */
+ FTALKING_I, /* (internal): initial shell was interactive */
+ FNFLAGS /* (place holder: how many flags are there) */
+};
+
+#define Flag(f) (shell_flags[(int) (f)])
+
+extern char shell_flags[FNFLAGS];
+
+extern char null[]; /* null value for variable */
+
+enum temp_type {
+ TT_HEREDOC_EXP, /* expanded heredoc */
+ TT_HIST_EDIT /* temp file used for history editing (fc -e) */
+};
+typedef enum temp_type Temp_type;
+/* temp/heredoc files. The file is removed when the struct is freed. */
+struct temp {
+ struct temp *next;
+ struct shf *shf;
+ int pid; /* pid of process parsed here-doc */
+ Temp_type type;
+ char *name;
+};
+
+/*
+ * stdio and our IO routines
+ */
+
+#define shl_spare (&shf_iob[0]) /* for c_read()/c_print() */
+#define shl_stdout (&shf_iob[1])
+#define shl_out (&shf_iob[2])
+extern int shl_stdout_ok;
+
+/*
+ * trap handlers
+ */
+typedef struct trap {
+ int signal; /* signal number */
+ const char *name; /* short name */
+ const char *mess; /* descriptive name */
+ char *trap; /* trap command */
+ volatile sig_atomic_t set; /* trap pending */
+ int flags; /* TF_* */
+ sig_t cursig; /* current handler (valid if TF_ORIG_* set) */
+ sig_t shtrap; /* shell signal handler */
+} Trap;
+
+/* values for Trap.flags */
+#define TF_SHELL_USES BIT(0) /* shell uses signal, user can't change */
+#define TF_USER_SET BIT(1) /* user has (tried to) set trap */
+#define TF_ORIG_IGN BIT(2) /* original action was SIG_IGN */
+#define TF_ORIG_DFL BIT(3) /* original action was SIG_DFL */
+#define TF_EXEC_IGN BIT(4) /* restore SIG_IGN just before exec */
+#define TF_EXEC_DFL BIT(5) /* restore SIG_DFL just before exec */
+#define TF_DFL_INTR BIT(6) /* when received, default action is LINTR */
+#define TF_TTY_INTR BIT(7) /* tty generated signal (see j_waitj) */
+#define TF_CHANGED BIT(8) /* used by runtrap() to detect trap changes */
+#define TF_FATAL BIT(9) /* causes termination if not trapped */
+
+/* values for setsig()/setexecsig() flags argument */
+#define SS_RESTORE_MASK 0x3 /* how to restore a signal before an exec() */
+#define SS_RESTORE_CURR 0 /* leave current handler in place */
+#define SS_RESTORE_ORIG 1 /* restore original handler */
+#define SS_RESTORE_DFL 2 /* restore to SIG_DFL */
+#define SS_RESTORE_IGN 3 /* restore to SIG_IGN */
+#define SS_FORCE BIT(3) /* set signal even if original signal ignored */
+#define SS_USER BIT(4) /* user is doing the set (ie, trap command) */
+#define SS_SHTRAP BIT(5) /* trap for internal use (CHLD,ALRM,WINCH) */
+
+#define SIGEXIT_ 0 /* for trap EXIT */
+#define SIGERR_ NSIG /* for trap ERR */
+
+extern volatile sig_atomic_t trap; /* traps pending? */
+extern volatile sig_atomic_t intrsig; /* pending trap interrupts command */
+extern volatile sig_atomic_t fatal_trap; /* received a fatal signal */
+extern volatile sig_atomic_t got_sigwinch;
+extern Trap sigtraps[NSIG+1];
+
+/*
+ * TMOUT support
+ */
+/* values for ksh_tmout_state */
+enum tmout_enum {
+ TMOUT_EXECUTING = 0, /* executing commands */
+ TMOUT_READING, /* waiting for input */
+ TMOUT_LEAVING /* have timed out */
+};
+extern unsigned int ksh_tmout;
+extern enum tmout_enum ksh_tmout_state;
+
+/* For "You have stopped jobs" message */
+extern int really_exit;
+
+/*
+ * fast character classes
+ */
+#define C_ALPHA BIT(0) /* a-z_A-Z */
+/* was C_DIGIT */
+#define C_LEX1 BIT(2) /* \0 \t\n|&;<>() */
+#define C_VAR1 BIT(3) /* *@#!$-? */
+#define C_IFSWS BIT(4) /* \t \n (IFS white space) */
+#define C_SUBOP1 BIT(5) /* "=-+?" */
+#define C_SUBOP2 BIT(6) /* "#%" */
+#define C_IFS BIT(7) /* $IFS */
+#define C_QUOTE BIT(8) /* \n\t"#$&'()*;<>?[\`| (needing quoting) */
+
+extern short ctypes [];
+
+#define ctype(c, t) !!(ctypes[(unsigned char)(c)]&(t))
+#define letter(c) ctype(c, C_ALPHA)
+#define digit(c) isdigit((unsigned char)(c))
+#define letnum(c) (ctype(c, C_ALPHA) || isdigit((unsigned char)(c)))
+
+extern int ifs0; /* for "$*" */
+
+/* Argument parsing for built-in commands and getopts command */
+
+/* Values for Getopt.flags */
+#define GF_ERROR BIT(0) /* call errorf() if there is an error */
+#define GF_PLUSOPT BIT(1) /* allow +c as an option */
+#define GF_NONAME BIT(2) /* don't print argv[0] in errors */
+
+/* Values for Getopt.info */
+#define GI_MINUS BIT(0) /* an option started with -... */
+#define GI_PLUS BIT(1) /* an option started with +... */
+#define GI_MINUSMINUS BIT(2) /* arguments were ended with -- */
+
+typedef struct {
+ int optind;
+ int uoptind;/* what user sees in $OPTIND */
+ char *optarg;
+ int flags; /* see GF_* */
+ int info; /* see GI_* */
+ unsigned int p; /* 0 or index into argv[optind - 1] */
+ char buf[2]; /* for bad option OPTARG value */
+} Getopt;
+
+extern Getopt builtin_opt; /* for shell builtin commands */
+extern Getopt user_opt; /* parsing state for getopts builtin command */
+
+/* This for co-processes */
+
+typedef int Coproc_id; /* something that won't (realistically) wrap */
+struct coproc {
+ int read; /* pipe from co-process's stdout */
+ int readw; /* other side of read (saved temporarily) */
+ int write; /* pipe to co-process's stdin */
+ Coproc_id id; /* id of current output pipe */
+ int njobs; /* number of live jobs using output pipe */
+ void *job; /* 0 or job of co-process using input pipe */
+};
+extern struct coproc coproc;
+
+/* Used in jobs.c and by coprocess stuff in exec.c */
+extern sigset_t sm_default, sm_sigchld;
+
+extern const char ksh_version[];
+
+/* name of called builtin function (used by error functions) */
+extern char *builtin_argv0;
+extern int builtin_flag; /* flags of called builtin (SPEC_BI, etc.) */
+
+/* current working directory, and size of memory allocated for same */
+extern char *current_wd;
+extern int current_wd_size;
+
+#ifdef EDIT
+/* Minimum required space to work with on a line - if the prompt leaves less
+ * space than this on a line, the prompt is truncated.
+ */
+# define MIN_EDIT_SPACE 7
+/* Minimum allowed value for x_cols: 2 for prompt, 3 for " < " at end of line
+ */
+# define MIN_COLS (2 + MIN_EDIT_SPACE + 3)
+extern int x_cols; /* tty columns */
+#else
+# define x_cols 80 /* for pr_menu(exec.c) */
+#endif
+
+/* These to avoid bracket matching problems */
+#define OPAREN '('
+#define CPAREN ')'
+#define OBRACK '['
+#define CBRACK ']'
+#define OBRACE '{'
+#define CBRACE '}'
+
+/* Determine the location of the system (common) profile */
+#define KSH_SYSTEM_PROFILE "/etc/profile"
+
+/* Used by v_evaluate() and setstr() to control action when error occurs */
+#define KSH_UNWIND_ERROR 0 /* unwind the stack (longjmp) */
+#define KSH_RETURN_ERROR 1 /* return 1/0 for success/failure */
+
+#include "shf.h"
+#include "table.h"
+#include "tree.h"
+#include "expand.h"
+#include "lex.h"
+
+/* alloc.c */
+Area * ainit(Area *);
+void afreeall(Area *);
+void * alloc(size_t, Area *);
+void * areallocarray(void *, size_t, size_t, Area *);
+void * aresize(void *, size_t, Area *);
+void afree(void *, Area *);
+/* c_ksh.c */
+int c_cd(char **);
+int c_pwd(char **);
+int c_print(char **);
+int c_whence(char **);
+int c_command(char **);
+int c_typeset(char **);
+int c_alias(char **);
+int c_unalias(char **);
+int c_let(char **);
+int c_jobs(char **);
+int c_fgbg(char **);
+int c_kill(char **);
+void getopts_reset(int);
+int c_getopts(char **);
+int c_bind(char **);
+/* c_sh.c */
+int c_label(char **);
+int c_shift(char **);
+int c_umask(char **);
+int c_dot(char **);
+int c_wait(char **);
+int c_read(char **);
+int c_eval(char **);
+int c_trap(char **);
+int c_brkcont(char **);
+int c_exitreturn(char **);
+int c_set(char **);
+int c_unset(char **);
+int c_ulimit(char **);
+int c_times(char **);
+int timex(struct op *, int, volatile int *);
+void timex_hook(struct op *, char ** volatile *);
+int c_exec(char **);
+int c_builtin(char **);
+/* c_test.c */
+int c_test(char **);
+/* edit.c: most prototypes in edit.h */
+void x_init(void);
+int x_read(char *, size_t);
+void set_editmode(const char *);
+/* emacs.c: most prototypes in edit.h */
+int x_bind(const char *, const char *, int, int);
+/* eval.c */
+char * substitute(const char *, int);
+char ** eval(char **, int);
+char * evalstr(char *cp, int);
+char * evalonestr(char *cp, int);
+char *debunk(char *, const char *, size_t);
+void expand(char *, XPtrV *, int);
+int glob_str(char *, XPtrV *, int);
+/* exec.c */
+int execute(struct op * volatile, volatile int, volatile int *);
+int shcomexec(char **);
+struct tbl * findfunc(const char *, unsigned int, int);
+int define(const char *, struct op *);
+void builtin(const char *, int (*)(char **));
+struct tbl * findcom(const char *, int);
+void flushcom(int);
+char * search(const char *, const char *, int, int *);
+int search_access(const char *, int, int *);
+int pr_menu(char *const *);
+int pr_list(char *const *);
+/* expr.c */
+int evaluate(const char *, long *, int, bool);
+int v_evaluate(struct tbl *, const char *, volatile int, bool);
+/* history.c */
+void init_histvec(void);
+void hist_init(Source *);
+void hist_finish(void);
+void histsave(int, const char *, int);
+#ifdef HISTORY
+int c_fc(char **);
+void sethistsize(int);
+void sethistfile(const char *);
+char ** histpos(void);
+int histnum(int);
+int findhist(int, int, const char *, int);
+int findhistrel(const char *);
+char **hist_get_newest(int);
+
+#endif /* HISTORY */
+/* io.c */
+void errorf(const char *, ...)
+ __attribute__((__noreturn__, __format__ (printf, 1, 2)));
+void warningf(bool, const char *, ...)
+ __attribute__((__format__ (printf, 2, 3)));
+void bi_errorf(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+void internal_errorf(int, const char *, ...)
+ __attribute__((__format__ (printf, 2, 3)));
+void error_prefix(int);
+void shellf(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+void shprintf(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+#ifdef KSH_DEBUG
+void kshdebug_init_(void);
+void kshdebug_printf_(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+void kshdebug_dump_(const char *, const void *, int);
+#endif /* KSH_DEBUG */
+int can_seek(int);
+void initio(void);
+int ksh_dup2(int, int, int);
+int savefd(int);
+void restfd(int, int);
+void openpipe(int *);
+void closepipe(int *);
+int check_fd(char *, int, const char **);
+void coproc_init(void);
+void coproc_read_close(int);
+void coproc_readw_close(int);
+void coproc_write_close(int);
+int coproc_getfd(int, const char **);
+void coproc_cleanup(int);
+struct temp *maketemp(Area *, Temp_type, struct temp **);
+/* jobs.c */
+void j_init(int);
+void j_suspend(void);
+void j_exit(void);
+void j_change(void);
+int exchild(struct op *, int, volatile int *, int);
+void startlast(void);
+int waitlast(void);
+int waitfor(const char *, int *);
+int j_kill(const char *, int);
+int j_resume(const char *, int);
+int j_jobs(const char *, int, int);
+int j_njobs(void);
+void j_notify(void);
+pid_t j_async(void);
+int j_stopped_running(void);
+/* mail.c */
+void mcheck(void);
+void mcset(long);
+void mbset(char *);
+void mpset(char *);
+/* main.c */
+int include(const char *, int, char **, int);
+int command(const char *, int);
+int shell(Source *volatile, int volatile);
+void unwind(int) __attribute__((__noreturn__));
+void newenv(int);
+void quitenv(struct shf *);
+void cleanup_parents_env(void);
+void cleanup_proc_env(void);
+/* misc.c */
+void setctypes(const char *, int);
+void initctypes(void);
+char * ulton(unsigned long, int);
+char * str_save(const char *, Area *);
+char * str_nsave(const char *, int, Area *);
+int option(const char *);
+char * getoptions(void);
+void change_flag(enum sh_flag, int, int);
+int parse_args(char **, int, int *);
+int getn(const char *, int *);
+int bi_getn(const char *, int *);
+int gmatch(const char *, const char *, int);
+int has_globbing(const char *, const char *);
+const unsigned char *pat_scan(const unsigned char *, const unsigned char *,
+ int);
+void qsortp(void **, size_t, int (*)(const void *, const void *));
+int xstrcmp(const void *, const void *);
+void ksh_getopt_reset(Getopt *, int);
+int ksh_getopt(char **, Getopt *, const char *);
+void print_value_quoted(const char *);
+void print_columns(struct shf *, int, char *(*)(void *, int, char *, int),
+ void *, int, int prefcol);
+int strip_nuls(char *, int);
+int blocking_read(int, char *, int);
+int reset_nonblock(int);
+char *ksh_get_wd(char *, int);
+/* path.c */
+int make_path(const char *, const char *, char **, XString *, int *);
+void simplify_path(char *);
+char *get_phys_path(const char *);
+void set_current_wd(char *);
+/* syn.c */
+void initkeywords(void);
+struct op * compile(Source *);
+/* trap.c */
+void inittraps(void);
+void alarm_init(void);
+Trap * gettrap(const char *, int);
+void trapsig(int);
+void intrcheck(void);
+int fatal_trap_check(void);
+int trap_pending(void);
+void runtraps(int intr);
+void runtrap(Trap *);
+void cleartraps(void);
+void restoresigs(void);
+void settrap(Trap *, char *);
+int block_pipe(void);
+void restore_pipe(int);
+int setsig(Trap *, sig_t, int);
+void setexecsig(Trap *, int);
+/* var.c */
+void newblock(void);
+void popblock(void);
+void initvar(void);
+struct tbl * global(const char *);
+struct tbl * local(const char *, bool);
+char * str_val(struct tbl *);
+long intval(struct tbl *);
+int setstr(struct tbl *, const char *, int);
+struct tbl *setint_v(struct tbl *, struct tbl *, bool);
+void setint(struct tbl *, long);
+int getint(struct tbl *, long *, bool);
+struct tbl *typeset(const char *, int, int, int, int);
+void unset(struct tbl *, int);
+char * skip_varname(const char *, int);
+char *skip_wdvarname(const char *, int);
+int is_wdvarname(const char *, int);
+int is_wdvarassign(const char *);
+char ** makenv(void);
+void change_random(void);
+int array_ref_len(const char *);
+char * arrayname(const char *);
+void set_array(const char *, int, char **);
+/* vi.c: see edit.h */