summaryrefslogtreecommitdiffstats
path: root/src/kash/shinstance.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/kash/shinstance.h606
1 files changed, 606 insertions, 0 deletions
diff --git a/src/kash/shinstance.h b/src/kash/shinstance.h
new file mode 100644
index 0000000..f181f33
--- /dev/null
+++ b/src/kash/shinstance.h
@@ -0,0 +1,606 @@
+/* $Id: shinstance.h 3480 2020-09-21 11:20:56Z bird $ */
+/** @file
+ * The shell instance and it's methods.
+ */
+
+/*
+ * Copyright (c) 2007-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
+ *
+ *
+ * This file is part of kBuild.
+ *
+ * kBuild 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.
+ *
+ * kBuild 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 kBuild; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef ___shinstance_h
+#define ___shinstance_h
+
+#include <stdio.h> /* BUFSIZ */
+#include <signal.h> /* NSIG */
+#ifndef _MSC_VER
+# include <termios.h>
+# include <sys/types.h>
+# include <sys/ioctl.h>
+# include <sys/resource.h>
+#endif
+#include <errno.h>
+#ifdef _MSC_VER
+# define EWOULDBLOCK 140
+#endif
+
+#include "shtypes.h"
+#include "shthread.h"
+#include "shfile.h"
+#include "shheap.h"
+#include "shell.h"
+#include "output.h"
+#include "options.h"
+
+#include "expand.h"
+#include "exec.h"
+#include "var.h"
+#include "show.h"
+
+#ifdef _MSC_VER
+# define strcasecmp stricmp
+# define strncasecmp strnicmp
+#endif
+
+#ifndef SH_FORKED_MODE
+extern shmtx g_sh_exec_inherit_mtx;
+#endif
+
+#ifndef SH_FORKED_MODE
+/**
+ * Subshell status.
+ */
+typedef struct shsubshellstatus
+{
+ unsigned volatile refs; /**< Reference counter. */
+ int volatile status; /**< The exit code. */
+ KBOOL volatile done; /**< Set if done (valid exit code). */
+ void *towaiton; /**< Event semaphore / whatever to wait on. */
+# if K_OS == K_OS_WINDOWS
+ uintptr_t volatile hThread; /**< The thread handle (child closes this). */
+# endif
+ struct shsubshellstatus *next; /**< Next free one on the free chain. */
+} shsubshellstatus;
+#else
+struct shsubshellstatus;
+#endif
+
+/**
+ * A child process.
+ */
+typedef struct shchild
+{
+ shpid pid; /**< The pid. */
+#if K_OS == K_OS_WINDOWS
+ void *hChild; /**< The handle to wait on. */
+#endif
+#ifndef SH_FORKED_MODE
+ shsubshellstatus *subshellstatus; /**< Pointer to the subshell status structure. NULL if child process. */
+#endif
+} shchild;
+
+/* memalloc.c */
+#define MINSIZE 504 /* minimum size of a block */
+struct stack_block {
+ struct stack_block *prev;
+ char space[MINSIZE];
+};
+
+#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
+/** Parser stack allocator block.
+ * These are reference counted so they can be shared between the parent and
+ * child shells. They are also using as an alternative to copying function
+ * definitions, here the final goal is to automatically emit separate
+ * pstack_blocks for function while parsing to make it more flexible. */
+typedef struct pstack_block {
+ /** Pointer to the next unallocated byte (= stacknxt). */
+ char *nextbyte;
+ /** Number of bytes available in the current stack block (= stacknleft). */
+ size_t avail;
+ /* Number of chars left for string data (PSTPUTC, PSTUPUTC, et al) (= sstrnleft). */
+ size_t strleft;
+ /** Top of the allocation stack (nextbyte points within this). */
+ struct stack_block *top;
+ /** Size of the top stack element (user space only). */
+ size_t topsize;
+ /** @name statistics
+ * @{ */
+ size_t allocations;
+ size_t bytesalloced;
+ size_t nodesalloced;
+ size_t entriesalloced;
+ size_t strbytesalloced;
+ size_t blocks;
+ size_t fragmentation;
+ /** @} */
+ /** Reference counter. */
+ unsigned volatile refs;
+ /** Whether to make it current when is restored to the top of the stack. */
+ KBOOL done;
+ /** The first stack block. */
+ struct stack_block first;
+} pstack_block;
+#endif
+
+/* input.c */
+struct strpush {
+ struct strpush *prev; /* preceding string on stack */
+ char *prevstring;
+ int prevnleft;
+ int prevlleft;
+ struct alias *ap; /* if push was associated with an alias */
+};
+
+/*
+ * The parsefile structure pointed to by the global variable parsefile
+ * contains information about the current file being read.
+ */
+struct parsefile {
+ struct parsefile *prev; /* preceding file on stack */
+ int linno; /* current line */
+ int fd; /* file descriptor (or -1 if string) */
+ int nleft; /* number of chars left in this line */
+ int lleft; /* number of chars left in this buffer */
+ char *nextc; /* next char in buffer */
+ char *buf; /* input buffer */
+ struct strpush *strpush; /* for pushing strings at this level */
+ struct strpush basestrpush; /* so pushing one is fast */
+};
+
+/* exec.c */
+#define CMDTABLESIZE 31 /* should be prime */
+#define ARB 1 /* actual size determined at run time */
+
+struct tblentry {
+ struct tblentry *next; /* next entry in hash chain */
+ union param param; /* definition of builtin function */
+ short cmdtype; /* index identifying command */
+ char rehash; /* if set, cd done since entry created */
+ char cmdname[ARB]; /* name of command */
+};
+
+/* expand.c */
+/*
+ * Structure specifying which parts of the string should be searched
+ * for IFS characters.
+ */
+struct ifsregion {
+ struct ifsregion *next; /* next region in list */
+ int begoff; /* offset of start of region */
+ int endoff; /* offset of end of region */
+ int inquotes; /* search for nul bytes only */
+};
+
+/* redir.c */
+struct redirtab {
+ struct redirtab *next;
+ short renamed[10];
+};
+
+/**
+ * This is a replacement for temporary node field nfile.expfname.
+ * Uses stack allocator, created by expredir(), duplicated by
+ * subshellinitredir() and popped (but not freed) by expredircleanup().
+ */
+typedef struct redirexpfnames
+{
+ struct redirexpfnames *prev; /**< Previous record. */
+ unsigned depth; /**< Nesting depth. */
+ unsigned count; /**< Number of expanded filenames in the array. */
+ char *names[1]; /**< Variable size. */
+} redirexpfnames;
+
+
+/**
+ * A shell instance.
+ *
+ * This is the core structure of the shell, it contains all
+ * the data associated with a shell process except that it's
+ * running in a thread and not a separate process.
+ */
+struct shinstance
+{
+ struct shinstance *next; /**< The next shell instance. */
+ struct shinstance *prev; /**< The previous shell instance. */
+ struct shinstance *parent; /**< The parent shell instance. */
+ shpid pid; /**< The (fake) process id of this shell instance. */
+ shtid tid; /**< The thread identifier of the thread for this shell. */
+ shpid pgid; /**< Process group ID. */
+ shfdtab fdtab; /**< The file descriptor table. */
+ shsigaction_t sigactions[NSIG]; /**< The signal actions registered with this shell instance. */
+ shsigset_t sigmask; /**< Our signal mask. */
+ char **shenviron; /**< The environment vector. */
+ int linked; /**< Set if we're still linked. */
+ unsigned num_children; /**< Number of children in the array. */
+ shchild *children; /**< The child array. */
+#ifndef SH_FORKED_MODE
+ int (*thread)(struct shinstance *, void *); /**< The thread procedure. */
+ void *threadarg; /**< The thread argument. */
+ struct jmploc *exitjmp; /**< Long jump target in sh_thread_wrapper for use by sh__exit. */
+ shsubshellstatus *subshellstatus; /**< Pointer to the subshell status structure (NULL if root). */
+#endif
+
+ /* alias.c */
+#define ATABSIZE 39
+ struct alias *atab[ATABSIZE];
+ unsigned aliases; /**< Number of active aliases. */
+
+ /* cd.c */
+ char *curdir; /**< current working directory */
+ char *prevdir; /**< previous working directory */
+ char *cdcomppath; /**< (stalloc) */
+ int getpwd_first; /**< static in getpwd. (initialized to 1!) */
+
+ /* error.h */
+ struct jmploc *handler;
+ int exception;
+ int exerrno/* = 0 */; /**< Last exec error */
+ int volatile suppressint;
+ int volatile intpending;
+
+ /* error.c */
+ char errmsg_buf[16]; /**< static in errmsg. (bss) */
+
+ /* eval.h */
+ char *commandname; /**< currently executing command */
+ int exitstatus; /**< exit status of last command */
+ int back_exitstatus;/**< exit status of backquoted command */
+ struct strlist *cmdenviron; /**< environment for builtin command (varlist from evalcommand()) */
+ int funcnest; /**< depth of function calls */
+ int evalskip; /**< set if we are skipping commands */
+ int skipcount; /**< number of levels to skip */
+ int loopnest; /**< current loop nesting level */
+ int commandnamemalloc; /**< Set if commandname is malloc'ed (only subshells). */
+
+ /* expand.c */
+ char *expdest; /**< output of current string (stack) */
+ struct nodelist *argbackq; /**< list of back quote expressions */
+ struct ifsregion ifsfirst; /**< first struct in list of ifs regions */
+ struct ifsregion *ifslastp; /**< last struct in list */
+ struct arglist exparg; /**< holds expanded arg list (stack) */
+ char *expdir; /**< Used by expandmeta. */
+
+ /* exec.h */
+ const char *pathopt; /**< set by padvance */
+
+ /* exec.c */
+ struct tblentry *cmdtable[CMDTABLESIZE];
+ int builtinloc/* = -1*/; /**< index in path of %builtin, or -1 */
+
+ /* input.h */
+ int plinno/* = 1 */;/**< input line number */
+ int parsenleft; /**< number of characters left in input buffer */
+ char *parsenextc; /**< next character in input buffer */
+ int init_editline/* = 0 */; /**< 0 == not setup, 1 == OK, -1 == failed */
+
+ /* input.c */
+ int parselleft; /**< copy of parsefile->lleft */
+ struct parsefile basepf; /**< top level input file */
+ char basebuf[BUFSIZ];/**< buffer for top level input file */
+ struct parsefile *parsefile/* = &basepf*/; /**< current input file */
+#ifndef SMALL
+ EditLine *el; /**< cookie for editline package */
+#endif
+
+ /* jobs.h */
+ shpid backgndpid/* = -1 */; /**< pid of last background process */
+ int job_warning; /**< user was warned about stopped jobs */
+
+ /* jobs.c */
+ struct job *jobtab; /**< array of jobs */
+ int njobs; /**< size of array */
+ int jobs_invalid; /**< set in child */
+ shpid initialpgrp; /**< pgrp of shell on invocation */
+ int curjob/* = -1*/;/**< current job */
+ int ttyfd/* = -1*/;
+ int jobctl; /**< job control enabled / disabled */
+ char *cmdnextc;
+ int cmdnleft;
+
+
+ /* mail.c */
+#define MAXMBOXES 10
+ int nmboxes; /**< number of mailboxes */
+ time_t mailtime[MAXMBOXES]; /**< times of mailboxes */
+
+ /* main.h */
+ shpid rootpid; /**< pid of main shell. */
+ int rootshell; /**< true if we aren't a child of the main shell. */
+ struct shinstance *psh_rootshell; /**< The root shell pointer. (!rootshell) */
+
+ /* memalloc.h */
+ char *stacknxt/* = stackbase.space*/;
+ int stacknleft/* = MINSIZE*/;
+ int sstrnleft;
+ int herefd/* = -1 */;
+
+ /* memalloc.c */
+ struct stack_block stackbase;
+ struct stack_block *stackp/* = &stackbase*/;
+ struct stackmark *markp;
+
+#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
+ pstack_block *curpstack; /**< The pstack entry we're currently allocating from (NULL when not in parse.c). */
+ pstack_block **pstack; /**< Stack of parsed stuff. */
+ unsigned pstacksize; /**< Number of entries in pstack. */
+ unsigned pstackalloced; /**< The allocated size of pstack. */
+ pstack_block *freepstack; /**< One cached pstack entry (lots of parsecmd calls). */
+#endif
+
+ /* myhistedit.h */
+ int displayhist;
+#ifndef SMALL
+ History *hist;
+ EditLine *el;
+#endif
+
+ /* output.h */
+ struct output output;
+ struct output errout;
+ struct output memout;
+ struct output *out1;
+ struct output *out2;
+
+ /* output.c */
+#define OUTBUFSIZ BUFSIZ
+#define MEM_OUT -3 /**< output to dynamically allocated memory */
+
+ /* options.h */
+ struct optent optlist[NOPTS];
+ char *minusc; /**< argument to -c option */
+ char *arg0; /**< $0 */
+ struct shparam shellparam; /**< $@ */
+ char **argptr; /**< argument list for builtin commands */
+ char *optionarg; /**< set by nextopt */
+ char *optptr; /**< used by nextopt */
+ char **orgargv; /**< The original argument vector (for cleanup). */
+ int arg0malloc; /**< Indicates whether arg0 was allocated or is part of orgargv. */
+
+ /* parse.h */
+ int tokpushback;
+ int whichprompt; /**< 1 == PS1, 2 == PS2 */
+
+ /* parser.c */
+ int noalias/* = 0*/;/**< when set, don't handle aliases */
+ struct heredoc *heredoclist; /**< list of here documents to read */
+ int parsebackquote; /**< nonzero if we are inside backquotes */
+ int doprompt; /**< if set, prompt the user */
+ int needprompt; /**< true if interactive and at start of line */
+ int lasttoken; /**< last token read */
+ char *wordtext; /**< text of last word returned by readtoken */
+ int checkkwd; /**< 1 == check for kwds, 2 == also eat newlines */
+ struct nodelist *backquotelist;
+ union node *redirnode;
+ struct heredoc *heredoc;
+ int quoteflag; /**< set if (part of) last token was quoted */
+ int startlinno; /**< line # where last token started */
+
+ /* redir.c */
+ struct redirtab *redirlist;
+ int fd0_redirected/* = 0*/;
+ redirexpfnames *expfnames; /**< Expanded filenames for current redirection setup. */
+
+ /* show.c */
+ char tracebuf[1024];
+ size_t tracepos;
+ int tracefd;
+
+ /* trap.h */
+ int pendingsigs; /**< indicates some signal received */
+
+ /* trap.c */
+ char gotsig[NSIG]; /**< indicates specified signal received */
+ char *trap[NSIG+1]; /**< trap handler commands */
+ char sigmode[NSIG]; /**< current value of signal */
+
+ /* var.h */
+ struct localvar *localvars;
+ struct var vatty;
+ struct var vifs;
+ struct var vmail;
+ struct var vmpath;
+ struct var vpath;
+#ifdef _MSC_VER
+ struct var vpath2;
+#endif
+ struct var vps1;
+ struct var vps2;
+ struct var vps4;
+#ifndef SMALL
+ struct var vterm;
+ struct var vhistsize;
+#endif
+ struct var voptind;
+#ifdef PC_OS2_LIBPATHS
+ struct var libpath_vars[4];
+#endif
+#ifdef SMALL
+# define VTABSIZE 39
+#else
+# define VTABSIZE 517
+#endif
+ struct var *vartab[VTABSIZE];
+
+ /* builtins.h */
+
+ /* bltin/test.c */
+ char **t_wp;
+ struct t_op const *t_wp_op;
+};
+
+extern void sh_init_globals(void);
+extern shinstance *sh_create_root_shell(char **, char **);
+extern shinstance *sh_create_child_shell(shinstance *);
+
+/* environment & pwd.h */
+char *sh_getenv(shinstance *, const char *);
+char **sh_environ(shinstance *);
+const char *sh_gethomedir(shinstance *, const char *);
+
+/* signals */
+#define SH_SIG_UNK ((shsig_t)(intptr_t)-199)
+#define SH_SIG_DFL ((shsig_t)(intptr_t)SIG_DFL)
+#define SH_SIG_IGN ((shsig_t)(intptr_t)SIG_IGN)
+#define SH_SIG_ERR ((shsig_t)(intptr_t)SIG_ERR)
+#ifdef _MSC_VER
+# define SA_RESTART 0x02
+# define SIG_BLOCK 1
+# define SIG_UNBLOCK 2
+# define SIG_SETMASK 3
+
+# define SIGHUP 1 /* _SIGHUP_IGNORE */
+/*# define SIGINT 2 */
+# define SIGQUIT 3 /* _SIGQUIT_IGNORE */
+/*# define SIGILL 4 */
+/*# define SIGFPE 8 */
+/*# define SIGSEGV 11 */
+# define SIGPIPE 13 /* _SIGPIPE_IGNORE */
+/*# define SIGTERM 15 */
+# define SIGTTIN 16 /* _SIGIOINT_IGNORE */
+# define SIGTSTP 17 /* _SIGSTOP_IGNORE */
+# define SIGTTOU 18
+# define SIGCONT 20
+/*# define SIGBREAK 21 */
+/*# define SIGABRT 22 */
+const char *strsignal(int iSig);
+#endif /* _MSC_VER */
+#ifndef HAVE_SYS_SIGNAME
+extern const char * const sys_signame[NSIG];
+#endif
+
+int sh_sigaction(shinstance *, int, const struct shsigaction *, struct shsigaction *);
+shsig_t sh_signal(shinstance *, int, shsig_t);
+int sh_siginterrupt(shinstance *, int, int);
+void sh_sigemptyset(shsigset_t *);
+void sh_sigfillset(shsigset_t *);
+void sh_sigaddset(shsigset_t *, int);
+void sh_sigdelset(shsigset_t *, int);
+int sh_sigismember(shsigset_t const *, int);
+int sh_sigprocmask(shinstance *, int, shsigset_t const *, shsigset_t *);
+SH_NORETURN_1 void sh_abort(shinstance *) SH_NORETURN_2;
+void sh_raise_sigint(shinstance *);
+int sh_kill(shinstance *, shpid, int);
+int sh_killpg(shinstance *, shpid, int);
+
+/* times */
+#include <time.h>
+#ifdef _MSC_VER
+ typedef struct shtms
+ {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+ } shtms;
+#else
+# include <sys/times.h>
+ typedef struct tms shtms;
+#endif
+clock_t sh_times(shinstance *, shtms *);
+int sh_sysconf_clk_tck(void);
+
+/* wait / process */
+int sh_add_child(shinstance *psh, shpid pid, void *hChild, struct shsubshellstatus *sts);
+#ifdef _MSC_VER
+# include <process.h>
+# define WNOHANG 1 /* Don't hang in wait. */
+# define WUNTRACED 2 /* Tell about stopped, untraced children. */
+# define WCONTINUED 4 /* Report a job control continued process. */
+# define _W_INT(w) (*(int *)&(w)) /* Convert union wait to int. */
+# define WCOREFLAG 0200
+# define _WSTATUS(x) (_W_INT(x) & 0177)
+# define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
+# define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
+# define WSTOPSIG(x) (_W_INT(x) >> 8)
+# define WIFSIGNALED(x) (_WSTATUS(x) != 0 && !WIFSTOPPED(x) && !WIFCONTINUED(x)) /* bird: made GLIBC tests happy. */
+# define WTERMSIG(x) (_WSTATUS(x))
+# define WIFEXITED(x) (_WSTATUS(x) == 0)
+# define WEXITSTATUS(x) (_W_INT(x) >> 8)
+# define WIFCONTINUED(x) (x == 0x13) /* 0x13 == SIGCONT */
+# define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
+# define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
+# define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
+#else
+# include <sys/wait.h>
+# ifdef __HAIKU__
+# define WCOREDUMP(x) WIFCORED(x)
+# endif
+#endif
+#ifdef SH_FORKED_MODE
+shpid sh_fork(shinstance *);
+#else
+shpid sh_thread_start(shinstance *pshparent, shinstance *pshchild, int (*thread)(shinstance *, void *), void *arg);
+#endif
+shpid sh_waitpid(shinstance *, shpid, int *, int);
+SH_NORETURN_1 void sh__exit(shinstance *, int) SH_NORETURN_2;
+int sh_execve(shinstance *, const char *, const char * const*, const char * const *);
+uid_t sh_getuid(shinstance *);
+uid_t sh_geteuid(shinstance *);
+gid_t sh_getgid(shinstance *);
+gid_t sh_getegid(shinstance *);
+shpid sh_getpid(shinstance *);
+shpid sh_getpgrp(shinstance *);
+shpid sh_getpgid(shinstance *, shpid);
+int sh_setpgid(shinstance *, shpid, shpid);
+
+/* tc* */
+shpid sh_tcgetpgrp(shinstance *, int);
+int sh_tcsetpgrp(shinstance *, int, shpid);
+
+/* sys/resource.h */
+#ifdef _MSC_VER
+ typedef int64_t shrlim_t;
+ typedef struct shrlimit
+ {
+ shrlim_t rlim_cur;
+ shrlim_t rlim_max;
+ } shrlimit;
+# define RLIMIT_CPU 0
+# define RLIMIT_FSIZE 1
+# define RLIMIT_DATA 2
+# define RLIMIT_STACK 3
+# define RLIMIT_CORE 4
+# define RLIMIT_RSS 5
+# define RLIMIT_MEMLOCK 6
+# define RLIMIT_NPROC 7
+# define RLIMIT_NOFILE 8
+# define RLIMIT_SBSIZE 9
+# define RLIMIT_VMEM 10
+# define RLIM_NLIMITS 11
+# define RLIM_INFINITY (0x7fffffffffffffffLL)
+#else
+ typedef rlim_t shrlim_t;
+ typedef struct rlimit shrlimit;
+#endif
+int sh_getrlimit(shinstance *, int, shrlimit *);
+int sh_setrlimit(shinstance *, int, const shrlimit *);
+
+/* string.h */
+const char *sh_strerror(shinstance *, int);
+
+#ifdef DEBUG
+# define TRACE2(param) trace param
+# define TRACE2V(param) tracev param
+#else
+# define TRACE2(param) do { } while (0)
+# define TRACE2V(param) do { } while (0)
+#endif
+
+#endif