#include "config.h"
#include <limits.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <signal.h>
#include <stdbool.h>
#define NELEM(a) (sizeof(a) / sizeof((a)[0]))
#define BIT(i) (1<<(i))
#define NUFILE 32
#define FDBASE 10
#define BITS(t) (CHAR_BIT * sizeof(t))
#define MAGIC (7)
#define ISMAGIC(c) ((unsigned char)(c) == MAGIC)
#define LINE 4096
extern const char *kshname;
extern pid_t kshpid;
extern pid_t procpid;
extern uid_t ksheuid;
extern int exstat;
extern int subst_exstat;
extern const char *safe_prompt;
extern char username[];
extern int disable_subst;
typedef struct Area {
struct link *freelist;
} Area;
extern Area aperm;
#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
# define kshdebug_init()
# define kshdebug_printf(a)
# define kshdebug_dump(a)
#endif
struct env {
short type;
short flags;
Area area;
struct block *loc;
short *savefd;
struct env *oenv;
sigjmp_buf jbuf;
struct temp *temps;
};
extern struct env *genv;
#define E_NONE 0
#define E_PARSE 1
#define E_FUNC 2
#define E_INCL 3
#define E_EXEC 4
#define E_LOOP 5
#define E_ERRH 6
#define EF_FUNC_PARSE BIT(0)
#define EF_BRKCONT_PASS BIT(1)
#define EF_FAKE_SIGDIE BIT(2)
#define STOP_BRKCONT(t) ((t) == E_NONE || (t) == E_PARSE \
|| (t) == E_FUNC || (t) == E_INCL)
#define STOP_RETURN(t) ((t) == E_FUNC || (t) == E_INCL)
#define LRETURN 1
#define LEXIT 2
#define LERROR 3
#define LLEAVE 4
#define LINTR 5
#define LBREAK 6
#define LCONTIN 7
#define LSHELL 8
#define LAEXPR 9
#define OF_CMDLINE 0x01
#define OF_SET 0x02
#define OF_SPECIAL 0x04
#define OF_INTERNAL 0x08
#define OF_ANY (OF_CMDLINE | OF_SET | OF_SPECIAL | OF_INTERNAL)
struct option {
const char *name;
char c;
short flags;
};
extern const struct option sh_options[];
enum sh_flag {
FEXPORT = 0,
FBRACEEXPAND,
FBGNICE,
FCOMMAND,
FCSHHISTORY,
#ifdef EMACS
FEMACS,
#endif
FERREXIT,
#ifdef EMACS
FGMACS,
#endif
FIGNOREEOF,
FTALKING,
FKEYWORD,
FLOGIN,
FMARKDIRS,
FMONITOR,
FNOCLOBBER,
FNOEXEC,
FNOGLOB,
FNOHUP,
FNOLOG,
FNOTIFY,
FNOUNSET,
FPHYSICAL,
FPIPEFAIL,
FPOSIX,
FPRIVILEGED,
FRESTRICTED,
FSH,
FSTDIN,
FTRACKALL,
FVERBOSE,
#ifdef VI
FVI,
FVIRAW,
FVISHOW8,
FVITABCOMPLETE,
FVIESCCOMPLETE,
#endif
FXTRACE,
FTALKING_I,
FNFLAGS
};
#define Flag(f) (shell_flags[(int) (f)])
extern char shell_flags[FNFLAGS];
extern char null[];
enum temp_type {
TT_HEREDOC_EXP,
TT_HIST_EDIT
};
typedef enum temp_type Temp_type;
struct temp {
struct temp *next;
struct shf *shf;
int pid;
Temp_type type;
char *name;
};
#define shl_spare (&shf_iob[0])
#define shl_stdout (&shf_iob[1])
#define shl_out (&shf_iob[2])
extern int shl_stdout_ok;
typedef struct trap {
int signal;
const char *name;
const char *mess;
char *trap;
volatile sig_atomic_t set;
int flags;
sig_t cursig;
sig_t shtrap;
} Trap;
#define TF_SHELL_USES BIT(0)
#define TF_USER_SET BIT(1)
#define TF_ORIG_IGN BIT(2)
#define TF_ORIG_DFL BIT(3)
#define TF_EXEC_IGN BIT(4)
#define TF_EXEC_DFL BIT(5)
#define TF_DFL_INTR BIT(6)
#define TF_TTY_INTR BIT(7)
#define TF_CHANGED BIT(8)
#define TF_FATAL BIT(9)
#define SS_RESTORE_MASK 0x3
#define SS_RESTORE_CURR 0
#define SS_RESTORE_ORIG 1
#define SS_RESTORE_DFL 2
#define SS_RESTORE_IGN 3
#define SS_FORCE BIT(3)
#define SS_USER BIT(4)
#define SS_SHTRAP BIT(5)
#define SIGEXIT_ 0
#define SIGERR_ NSIG
extern volatile sig_atomic_t trap;
extern volatile sig_atomic_t intrsig;
extern volatile sig_atomic_t fatal_trap;
extern volatile sig_atomic_t got_sigwinch;
extern Trap sigtraps[NSIG+1];
enum tmout_enum {
TMOUT_EXECUTING = 0,
TMOUT_READING,
TMOUT_LEAVING
};
extern unsigned int ksh_tmout;
extern enum tmout_enum ksh_tmout_state;
extern int really_exit;
#define C_ALPHA BIT(0)
#define C_LEX1 BIT(2)
#define C_VAR1 BIT(3)
#define C_IFSWS BIT(4)
#define C_SUBOP1 BIT(5)
#define C_SUBOP2 BIT(6)
#define C_IFS BIT(7)
#define C_QUOTE BIT(8)
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;
#define GF_ERROR BIT(0)
#define GF_PLUSOPT BIT(1)
#define GF_NONAME BIT(2)
#define GI_MINUS BIT(0)
#define GI_PLUS BIT(1)
#define GI_MINUSMINUS BIT(2)
typedef struct {
int optind;
int uoptind;
char *optarg;
int flags;
int info;
unsigned int p;
char buf[2];
} Getopt;
extern Getopt builtin_opt;
extern Getopt user_opt;
typedef int Coproc_id;
struct coproc {
int read;
int readw;
int write;
Coproc_id id;
int njobs;
void *job;
};
extern struct coproc coproc;
extern sigset_t sm_default, sm_sigchld;
extern const char ksh_version[];
extern char *builtin_argv0;
extern int builtin_flag;
extern char *current_wd;
extern int current_wd_size;
#define MIN_EDIT_SPACE 7
#define MIN_COLS (2 + MIN_EDIT_SPACE + 3)
extern int x_cols;
#define OPAREN '('
#define CPAREN ')'
#define OBRACK '['
#define CBRACK ']'
#define OBRACE '{'
#define CBRACE '}'
#define KSH_SYSTEM_PROFILE "/etc/profile"
#define KSH_UNWIND_ERROR 0x0
#define KSH_RETURN_ERROR 0x1
#define KSH_IGNORE_RDONLY 0x4
#include "shf.h"
#include "table.h"
#include "tree.h"
#include "expand.h"
#include "lex.h"
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 *);
int c_cd(char **);
int c_pwd(char **);
int c_print(char **);
int c_whence(char **);
int c_command(char **);
int c_type(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 **);
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 **);
int c_test(char **);
void x_init(void);
int x_read(char *, size_t);
void set_editmode(const char *);
int x_bind(const char *, const char *, int, int);
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);
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 evaluate(const char *, int64_t *, int, bool);
int v_evaluate(struct tbl *, const char *, volatile int, bool);
void init_histvec(void);
void hist_init(Source *);
void hist_finish(void);
void histsave(int, const char *, int);
int c_fc(char **);
void c_fc_reset(void);
void sethistcontrol(const 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);
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(const char *, ...)
__attribute__((__noreturn__, __format__ (printf, 1, 2)));
void internal_warningf(const char *, ...)
__attribute__((__format__ (printf, 1, 2)));
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
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 **);
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);
void mcheck(void);
void mcset(int64_t);
void mbset(char *);
void mpset(char *);
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);
void setctypes(const char *, int);
void initctypes(void);
char * u64ton(uint64_t, 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);
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 *);
void initkeywords(void);
struct op * compile(Source *);
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);
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 *);
int64_t intval(struct tbl *);
int setstr(struct tbl *, const char *, int);
struct tbl *setint_v(struct tbl *, struct tbl *, bool);
void setint(struct tbl *, int64_t);
int getint(struct tbl *, int64_t *, 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 **);
void initcurses(void);