mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
[shp cleanup 00] Reunify the original sh state struct
As observed previously (see3654ee73
,7e6bbf85
,79d19458
), the ksh 93u+ codebase on which we rebased development was in a transition: AT&T evidently wanted to make it possible to have several shell interpreter states in the same process, which in theory would have made it possible to start a complete new shell (not just a subshell) without forking a new process. This required transitioning from accessing the 'sh' state struct directly to accessing it via pointers (usually but not always called 'shp'), introducing a lot of bug-prone passing around of those pointers via function arguments and other state structs. Some of the original 'sh' struct was separated into a 'struct shared' called 'shgd' a.k.a. 'sh.gd' (global data) instead; these were global state variables that were going to be shared between the different main shell environments sharing a process. Yet, for some reason, that struct was allocated dynamically once at init time, requiring yet another pointer to access it. <shrug> None of this ever worked, because that transition was incomplete. It was much further along in the ksh 93v- beta, but I don't think it actually worked there either (not very much really did). So, starting a new shell has always required starting a new process. So, now that it's clear what they were trying to do, should we try to make it work? I'm going to go with a firm "no" on that question. Even non-forking (virtual) subshells, something quite a bit less ambitious, were already an unmitigated nightmare of bugs. In 93u+m we fixed a load of bugs related to those, but I'm sure there are still many left. At the very least there are multiple memory leaks. I think the ambition to go even further and have complete shells running separate programs share a process, particularly given the brittle and buggy state of the existing codebase, is evidence that the AT&T team, in the final years, had well and truly lost the ability to think "wait a minute, aren't we in over our heads here, and why are we doing this again? Is this *actually* a feasible and useful idea?" In my view, having entirely separate programs share a process is a *terrible*, horrible, no-good idea that takes us back to the bad old days before Unix, when kernels and CPUs were unable to enforce any memory access restrictions. Programmers are imperfect. If you're going to run a new program, you need the kernel to enforce the separation between programs, or you're just asking for memory corruption and security holes. And that separation is enforced by starting a new program in a new process. That's what processes are *for*. And if you need *that* to be radically performance-optimised then you're probably doing it wrong anyway. (By the way, I would still argue the same for subshells, even after we fixed many bugs in virtual subshells. But forking all subshells would in fact cause many scripts to slow down, and the community would surely revolt. <sigh> Maybe I should make it a shell option instead, so scripts can 'set -o subfork' for reliability.) It is also unclear how they were going to make something like 'ulimit' work, which can only work in a separate process. There was no sign of a mechanism to fork a separate program's shell mid-execution like there is for subshells (sh_subfork()). Anyway... I had already changed some code here and there to access the sh state struct directly, but as of this commit I'm beginning to properly undo this exercise in pointlessness. From now on, we're exercising pointerlessness instead. I'll do this in stages to make any problems introduced more traceable. Stage 0 restores the full 'sh' state struct to its former static glory and reverts 'shgd' as a separate entity. src/cmd/ksh93/sh/defs.c, src/cmd/ksh93/include/defs.h, src/cmd/ksh93/include/shell.h src/cmd/ksh93/Mamfile:: - Move 'struct sh_scoped' and 'struct limits' from defs.h to shell.h as the sh struct will need their complete definitions. - Get rid of 'struct shared' (shgd) in defs.h; its members are folded back into their original place, the main Shell_t struct (sh) in shell.h. There are no name conflicts. - Get rid of the _SH_PRIVATE macro in defs.h. The members it defines are now defined normally in the main Shell_t struct (sh) in shell.h. - To make this possible, move <history.h> and "fault.h" includes from defs.h to shell.h and update the Mamfile accordingly. - Turn sh_getinterp() and shgd into macros that resolve to (&sh). This will allow the compiler to optimise out many pointer dereferences already. - Keep extern sh_getinterp() for libshell ABI compatibility. src/cmd/ksh93/sh/init.c: - sh_init(): Do not calloc (sh_newof) the sh or shgd structs. - sh_getinterp(): Keep function for libshell ABI compat.
This commit is contained in:
parent
57ed1efc2c
commit
2d3ec8b67a
5 changed files with 306 additions and 311 deletions
|
@ -72,6 +72,89 @@ make install
|
|||
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/externs
|
||||
done FEATURE/externs generated
|
||||
make include/shell.h implicit
|
||||
make include/fault.h implicit
|
||||
make FEATURE/sigfeatures implicit
|
||||
meta FEATURE/sigfeatures features/%>FEATURE/% features/sigfeatures sigfeatures
|
||||
make features/sigfeatures
|
||||
done features/sigfeatures
|
||||
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/sigfeatures
|
||||
done FEATURE/sigfeatures dontcare generated
|
||||
make FEATURE/setjmp implicit
|
||||
meta FEATURE/setjmp features/%>FEATURE/% features/setjmp setjmp
|
||||
make features/setjmp
|
||||
done features/setjmp
|
||||
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/setjmp
|
||||
done FEATURE/setjmp dontcare generated
|
||||
prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/error.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/sig.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/sig.h dontcare
|
||||
done include/fault.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/stk.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/sfio.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/sfio_s.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_map.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_map.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/endian.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/bytesex.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/bytesex.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/endian.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_common.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/regex.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_api.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_api.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/wctype.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_wctype.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/wchar.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/wchar.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_wctype.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/wctype.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/stdio.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_stdio.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_stdio.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/stdio.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/stdio.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_wchar.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/regex.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/getopt.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_getopt.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/getopt.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_map.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_botch.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_botch.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_limits.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_limits.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_fcntl.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_fs.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_fcntl.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_sys.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/getopt.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_sys.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_lib.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_lib.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_std.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/sfio.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/stk.h dontcare
|
||||
make include/history.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
|
||||
done include/history.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/cmd.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/dlldefs.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/dlldefs.h dontcare
|
||||
|
@ -81,68 +164,7 @@ make install
|
|||
done ${PACKAGE_ast_INCLUDE}/cmdext.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/shcmd.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/stak.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/stk.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/sfio.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/sfio_s.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_map.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_map.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/endian.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/bytesex.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/bytesex.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/endian.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_common.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/regex.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_api.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_api.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/wctype.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_wctype.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/wchar.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/wchar.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_wctype.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/wctype.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/stdio.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_stdio.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_stdio.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/stdio.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/stdio.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_wchar.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/regex.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/getopt.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_getopt.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/getopt.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_map.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_botch.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_botch.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_limits.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_limits.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_fcntl.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_fs.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_fcntl.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_sys.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/getopt.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_sys.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/ast_lib.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_lib.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/ast_std.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/sfio.h dontcare
|
||||
done ${PACKAGE_ast_INCLUDE}/stk.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/stk.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/stak.h dontcare
|
||||
make ${PACKAGE_ast_INCLUDE}/error.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/option.h implicit
|
||||
|
@ -232,27 +254,6 @@ make install
|
|||
make include/argnod.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/stak.h implicit
|
||||
done include/argnod.h dontcare
|
||||
make include/fault.h implicit
|
||||
make FEATURE/sigfeatures implicit
|
||||
meta FEATURE/sigfeatures features/%>FEATURE/% features/sigfeatures sigfeatures
|
||||
make features/sigfeatures
|
||||
done features/sigfeatures
|
||||
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/sigfeatures
|
||||
done FEATURE/sigfeatures dontcare generated
|
||||
make FEATURE/setjmp implicit
|
||||
meta FEATURE/setjmp features/%>FEATURE/% features/setjmp setjmp
|
||||
make features/setjmp
|
||||
done features/setjmp
|
||||
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/setjmp
|
||||
done FEATURE/setjmp dontcare generated
|
||||
prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/error.h implicit
|
||||
make ${PACKAGE_ast_INCLUDE}/sig.h implicit
|
||||
done ${PACKAGE_ast_INCLUDE}/sig.h dontcare
|
||||
done include/fault.h dontcare
|
||||
make include/history.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
|
||||
done include/history.h dontcare
|
||||
prev ${PACKAGE_ast_INCLUDE}/cdt.h implicit
|
||||
prev FEATURE/options implicit
|
||||
prev FEATURE/externs implicit
|
||||
|
|
|
@ -51,8 +51,6 @@
|
|||
#include "FEATURE/externs"
|
||||
#include "FEATURE/options"
|
||||
#include <cdt.h>
|
||||
#include <history.h>
|
||||
#include "fault.h"
|
||||
#include "argnod.h"
|
||||
#include "name.h"
|
||||
#include <ctype.h>
|
||||
|
@ -64,216 +62,17 @@
|
|||
#define Empty ((char*)(e_sptbnl+3))
|
||||
|
||||
#define env_change() (++ast.env_serial)
|
||||
#define Env_t void
|
||||
#define sh_envput(e,p) env_change()
|
||||
#define env_delete(e,p) env_change()
|
||||
|
||||
extern char* sh_getenv(const char*);
|
||||
extern char* sh_setenviron(const char*);
|
||||
|
||||
struct sh_scoped
|
||||
{
|
||||
struct sh_scoped *prevst; /* pointer to previous state */
|
||||
int dolc;
|
||||
char **dolv;
|
||||
char *cmdname;
|
||||
char *filename;
|
||||
char *funname;
|
||||
int lineno;
|
||||
Dt_t *save_tree; /* var_tree for calling function */
|
||||
struct sh_scoped *self; /* pointer to copy of this scope */
|
||||
Dt_t *var_local; /* local level variables for name() */
|
||||
struct slnod *staklist; /* link list of function stacks */
|
||||
int states; /* shell state bits used by sh_isstate(), etc. */
|
||||
int breakcnt;
|
||||
int execbrk;
|
||||
int loopcnt;
|
||||
int firstline;
|
||||
int32_t optindex;
|
||||
int32_t optnum;
|
||||
int32_t tmout; /* value for TMOUT */
|
||||
short optchar;
|
||||
short opterror;
|
||||
int ioset;
|
||||
unsigned short trapmax;
|
||||
char *trap[SH_DEBUGTRAP+1];
|
||||
char **otrap;
|
||||
char **trapcom;
|
||||
char **otrapcom;
|
||||
void *timetrap;
|
||||
struct Ufunction *real_fun; /* current 'function name' function */
|
||||
int repl_index;
|
||||
char *repl_arg;
|
||||
};
|
||||
|
||||
struct limits
|
||||
{
|
||||
long arg_max; /* max arg+env exec() size */
|
||||
int open_max; /* maximum number of file descriptors */
|
||||
int clk_tck; /* number of ticks per second */
|
||||
int child_max; /* maximum number of children */
|
||||
};
|
||||
|
||||
#ifndef SH_wait_f_defined
|
||||
typedef int (*Shwait_f)(int, long, int);
|
||||
# define SH_wait_f_defined
|
||||
#endif
|
||||
|
||||
|
||||
struct shared
|
||||
{
|
||||
struct limits lim;
|
||||
uid_t userid;
|
||||
uid_t euserid;
|
||||
gid_t groupid;
|
||||
gid_t egroupid;
|
||||
pid_t pid; /* $$, the main shell's PID (invariable) */
|
||||
pid_t ppid; /* $PPID, the main shell's parent's PID */
|
||||
pid_t current_pid; /* ${.sh.pid}, PID of current ksh process (updates when subshell forks) */
|
||||
int realsubshell; /* ${.sh.subshell}, actual subshell level (including virtual and forked) */
|
||||
unsigned char sigruntime[2];
|
||||
Namval_t *bltin_nodes;
|
||||
Namval_t *bltin_cmds;
|
||||
History_t *hist_ptr;
|
||||
char *shpath;
|
||||
char *user;
|
||||
char **sigmsg;
|
||||
char **login_files;
|
||||
void *ed_context;
|
||||
int *stats;
|
||||
int sigmax;
|
||||
Shwait_f waitevent;
|
||||
};
|
||||
|
||||
#define __SH_PRIVATE_1 \
|
||||
struct shared *gd; /* global data */ \
|
||||
struct sh_scoped st; /* scoped information */ \
|
||||
Stk_t *stk; /* stack pointer */ \
|
||||
Sfio_t *heredocs; /* current here-doc temp file */ \
|
||||
Sfio_t *funlog; /* for logging function definitions */ \
|
||||
int **fdptrs; /* pointer to file numbers */ \
|
||||
char *lastarg; \
|
||||
char *lastpath; /* last absolute path found */ \
|
||||
int path_err; /* last error on path search */ \
|
||||
Dt_t *track_tree; /* for tracked aliases */ \
|
||||
Dt_t *var_base; /* global level variables */ \
|
||||
Dt_t *fun_base; /* global level functions */ \
|
||||
Dt_t *openmatch; \
|
||||
Namval_t *namespace; /* current active namespace */ \
|
||||
Namval_t *last_table; /* last table used in last nv_open */ \
|
||||
Namval_t *prev_table; /* previous table used in nv_open */ \
|
||||
Sfio_t *outpool; /* output stream pool */ \
|
||||
long timeout; /* read timeout */ \
|
||||
unsigned int curenv; /* current subshell number */ \
|
||||
unsigned int jobenv; /* subshell number for jobs */ \
|
||||
int infd; /* input file descriptor */ \
|
||||
short nextprompt; /* next prompt is PS<nextprompt> */ \
|
||||
Namval_t *posix_fun; /* points to last name() function */ \
|
||||
char *outbuff; /* pointer to output buffer */ \
|
||||
char *errbuff; /* pointer to stderr buffer */ \
|
||||
char *prompt; /* pointer to prompt string */ \
|
||||
char *shname; /* shell name */ \
|
||||
char *comdiv; /* points to sh -c argument */ \
|
||||
char *prefix; /* prefix for compound assignment */ \
|
||||
sigjmp_buf *jmplist; /* longjmp return stack */ \
|
||||
pid_t bckpid; /* background process id */ \
|
||||
pid_t cpid; \
|
||||
pid_t spid; /* subshell process id */ \
|
||||
pid_t pipepid; \
|
||||
pid_t outpipepid; \
|
||||
int topfd; \
|
||||
int savesig; \
|
||||
unsigned char *sigflag; /* pointer to signal states */ \
|
||||
char intrap; \
|
||||
char login_sh; \
|
||||
char lastbase; \
|
||||
char forked; \
|
||||
char binscript; \
|
||||
char funload; \
|
||||
char used_pos; /* used positional parameter */\
|
||||
char universe; \
|
||||
char winch; \
|
||||
short arithrecursion; /* current arithmetic recursion level */ \
|
||||
char indebug; /* set when in debug trap */ \
|
||||
unsigned char ignsig; /* ignored signal in subshell */ \
|
||||
unsigned char lastsig; /* last signal received */ \
|
||||
char pathinit; /* pathinit called from subshell */ \
|
||||
char comsub; /* set to 1 when in `...`, 2 when in ${ ...; }, 3 when in $(...) */ \
|
||||
char subshare; /* set when comsub==2 (shared-state ${ ...; } command substitution) */ \
|
||||
char toomany; /* set when out of fd's */ \
|
||||
char instance; /* in set_instance */ \
|
||||
char decomma; /* decimal_point=',' */ \
|
||||
char redir0; /* redirect of 0 */ \
|
||||
char *readscript; /* set before reading a script */ \
|
||||
int subdup; /* bitmask for dups of 1 */ \
|
||||
int *inpipe; /* input pipe pointer */ \
|
||||
int *outpipe; /* output pipe pointer */ \
|
||||
int cpipe[3]; \
|
||||
int coutpipe; \
|
||||
int inuse_bits; \
|
||||
struct argnod *envlist; \
|
||||
struct dolnod *arglist; \
|
||||
int fn_depth; \
|
||||
int fn_reset; \
|
||||
int dot_depth; \
|
||||
int hist_depth; \
|
||||
int xargmin; \
|
||||
int xargmax; \
|
||||
int xargexit; \
|
||||
int nenv; \
|
||||
mode_t mask; \
|
||||
Env_t *env; \
|
||||
void *init_context; \
|
||||
void *mac_context; \
|
||||
void *lex_context; \
|
||||
void *arg_context; \
|
||||
void *pathlist; \
|
||||
void *defpathlist; \
|
||||
void *cdpathlist; \
|
||||
char **argaddr; \
|
||||
void *optlist; \
|
||||
struct sh_scoped global; \
|
||||
struct checkpt checkbase; \
|
||||
Shinit_f userinit; \
|
||||
Shbltin_f bltinfun; \
|
||||
Shbltin_t bltindata; \
|
||||
char *cur_line; \
|
||||
int offsets[10]; \
|
||||
Sfio_t **sftable; \
|
||||
unsigned char *fdstatus; \
|
||||
const char *pwd; \
|
||||
void *jmpbuffer; \
|
||||
void *mktype; \
|
||||
Sfio_t *strbuf; \
|
||||
Sfio_t *strbuf2; \
|
||||
Dt_t *first_root; \
|
||||
Dt_t *prefix_root; \
|
||||
Dt_t *last_root; \
|
||||
Dt_t *prev_root; \
|
||||
Dt_t *fpathdict; \
|
||||
Dt_t *typedict; \
|
||||
Dt_t *inpool; \
|
||||
char ifstable[256]; \
|
||||
unsigned long test; \
|
||||
Shopt_t offoptions; /* options that were explicitly disabled by the user on the command line */ \
|
||||
Shopt_t glob_options; \
|
||||
Namval_t *typeinit; \
|
||||
Namfun_t nvfun; \
|
||||
char *mathnodes; \
|
||||
char *bltin_dir; \
|
||||
struct Regress_s*regress; \
|
||||
char exittrap; \
|
||||
char errtrap; \
|
||||
char end_fn;
|
||||
#if !SHOPT_DEVFD
|
||||
#define __SH_PRIVATE_2 \
|
||||
char *fifo; /* FIFO name for current process substitution */ \
|
||||
Dt_t *fifo_tree; /* for cleaning up process substitution FIFOs */
|
||||
#else
|
||||
#define __SH_PRIVATE_2
|
||||
#endif
|
||||
#define _SH_PRIVATE __SH_PRIVATE_1 __SH_PRIVATE_2
|
||||
|
||||
#include <shell.h>
|
||||
|
||||
#include "shtable.h"
|
||||
|
@ -325,7 +124,6 @@ struct shared
|
|||
#define SH_READEVAL 0x4000 /* for sh_eval */
|
||||
#define SH_FUNEVAL 0x10000 /* for sh_eval for function load */
|
||||
|
||||
extern struct shared *shgd;
|
||||
extern void sh_applyopts(Shell_t*,Shopt_t);
|
||||
extern char **sh_argbuild(Shell_t*,int*,const struct comnod*,int);
|
||||
extern struct dolnod *sh_argfree(Shell_t *, struct dolnod*,int);
|
||||
|
@ -450,4 +248,4 @@ extern const char e_dict[];
|
|||
# define sh_stats(x)
|
||||
#endif /* SHOPT_STATS */
|
||||
|
||||
#endif
|
||||
#endif /* !defs_h_defined */
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
* David Korn <dgk@research.att.com> *
|
||||
* *
|
||||
***********************************************************************/
|
||||
#ifndef SH_INTERACTIVE
|
||||
#ifndef shell_h_defined
|
||||
#define shell_h_defined
|
||||
/*
|
||||
* David Korn
|
||||
* AT&T Labs
|
||||
|
@ -27,15 +28,18 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define SH_VERSION 20071012
|
||||
#define SH_VERSION 20211229
|
||||
|
||||
#include <ast.h>
|
||||
#include <cdt.h>
|
||||
#ifdef _SH_PRIVATE
|
||||
#include <history.h>
|
||||
#include <stk.h>
|
||||
#ifdef defs_h_defined
|
||||
# include "name.h"
|
||||
#else
|
||||
# include <nval.h>
|
||||
#endif /* _SH_PRIVATE */
|
||||
#endif /* defs_h_defined */
|
||||
#include "fault.h"
|
||||
|
||||
/* options */
|
||||
typedef struct
|
||||
|
@ -168,6 +172,49 @@ typedef struct sh_scope
|
|||
struct sh_scope *self;
|
||||
} Shscope_t;
|
||||
|
||||
struct sh_scoped
|
||||
{
|
||||
struct sh_scoped *prevst; /* pointer to previous state */
|
||||
int dolc;
|
||||
char **dolv;
|
||||
char *cmdname;
|
||||
char *filename;
|
||||
char *funname;
|
||||
int lineno;
|
||||
Dt_t *save_tree; /* var_tree for calling function */
|
||||
struct sh_scoped *self; /* pointer to copy of this scope */
|
||||
Dt_t *var_local; /* local level variables for name() */
|
||||
struct slnod *staklist; /* link list of function stacks */
|
||||
int states; /* shell state bits used by sh_isstate(), etc. */
|
||||
int breakcnt;
|
||||
int execbrk;
|
||||
int loopcnt;
|
||||
int firstline;
|
||||
int32_t optindex;
|
||||
int32_t optnum;
|
||||
int32_t tmout; /* value for TMOUT */
|
||||
short optchar;
|
||||
short opterror;
|
||||
int ioset;
|
||||
unsigned short trapmax;
|
||||
char *trap[SH_DEBUGTRAP+1];
|
||||
char **otrap;
|
||||
char **trapcom;
|
||||
char **otrapcom;
|
||||
void *timetrap;
|
||||
struct Ufunction *real_fun; /* current 'function name' function */
|
||||
int repl_index;
|
||||
char *repl_arg;
|
||||
};
|
||||
|
||||
struct limits
|
||||
{
|
||||
long arg_max; /* max arg+env exec() size */
|
||||
int open_max; /* maximum number of file descriptors */
|
||||
int clk_tck; /* number of ticks per second */
|
||||
int child_max; /* maximum number of children */
|
||||
};
|
||||
|
||||
/*
|
||||
* Saves the state of the shell
|
||||
*/
|
||||
|
@ -186,9 +233,155 @@ struct Shell_s
|
|||
unsigned char trapnote; /* set when trap/signal is pending */
|
||||
char shcomp; /* set when running shcomp */
|
||||
unsigned int subshell; /* set for virtual subshell */
|
||||
#ifdef _SH_PRIVATE
|
||||
_SH_PRIVATE
|
||||
#endif /* _SH_PRIVATE */
|
||||
|
||||
/* These are the former 'struct shared' (shgd) members. */
|
||||
struct limits lim;
|
||||
uid_t userid;
|
||||
uid_t euserid;
|
||||
gid_t groupid;
|
||||
gid_t egroupid;
|
||||
pid_t pid; /* $$, the main shell's PID (invariable) */
|
||||
pid_t ppid; /* $PPID, the main shell's parent's PID */
|
||||
pid_t current_pid; /* ${.sh.pid}, PID of current ksh process (updates when subshell forks) */
|
||||
int realsubshell; /* ${.sh.subshell}, actual subshell level (including virtual and forked) */
|
||||
unsigned char sigruntime[2];
|
||||
Namval_t *bltin_nodes;
|
||||
Namval_t *bltin_cmds;
|
||||
History_t *hist_ptr;
|
||||
char *shpath;
|
||||
char *user;
|
||||
char **sigmsg;
|
||||
char **login_files;
|
||||
void *ed_context;
|
||||
int *stats;
|
||||
int sigmax;
|
||||
Shwait_f waitevent;
|
||||
|
||||
/* These are the members formerly defined via the _SH_PRIVATE macro.
|
||||
* Programs using libshell should not rely on them as they may change. */
|
||||
Shell_t *gd; /* pointer to self for backwards compatibility (was: global data) */
|
||||
struct sh_scoped st; /* scoped information */
|
||||
Stk_t *stk; /* stack pointer */
|
||||
Sfio_t *heredocs; /* current here-doc temp file */
|
||||
Sfio_t *funlog; /* for logging function definitions */
|
||||
int **fdptrs; /* pointer to file numbers */
|
||||
char *lastarg;
|
||||
char *lastpath; /* last absolute path found */
|
||||
int path_err; /* last error on path search */
|
||||
Dt_t *track_tree; /* for tracked aliases */
|
||||
Dt_t *var_base; /* global level variables */
|
||||
Dt_t *fun_base; /* global level functions */
|
||||
Dt_t *openmatch;
|
||||
Namval_t *namespace; /* current active namespace */
|
||||
Namval_t *last_table; /* last table used in last nv_open */
|
||||
Namval_t *prev_table; /* previous table used in nv_open */
|
||||
Sfio_t *outpool; /* output stream pool */
|
||||
long timeout; /* read timeout */
|
||||
unsigned int curenv; /* current subshell number */
|
||||
unsigned int jobenv; /* subshell number for jobs */
|
||||
int infd; /* input file descriptor */
|
||||
short nextprompt; /* next prompt is PS<nextprompt> */
|
||||
Namval_t *posix_fun; /* points to last name() function */
|
||||
char *outbuff; /* pointer to output buffer */
|
||||
char *errbuff; /* pointer to stderr buffer */
|
||||
char *prompt; /* pointer to prompt string */
|
||||
char *shname; /* shell name */
|
||||
char *comdiv; /* points to sh -c argument */
|
||||
char *prefix; /* prefix for compound assignment */
|
||||
sigjmp_buf *jmplist; /* longjmp return stack */
|
||||
pid_t bckpid; /* background process id */
|
||||
pid_t cpid;
|
||||
pid_t spid; /* subshell process id */
|
||||
pid_t pipepid;
|
||||
pid_t outpipepid;
|
||||
int topfd;
|
||||
int savesig;
|
||||
unsigned char *sigflag; /* pointer to signal states */
|
||||
char intrap;
|
||||
char login_sh;
|
||||
char lastbase;
|
||||
char forked;
|
||||
char binscript;
|
||||
char funload;
|
||||
char used_pos; /* used positional parameter */
|
||||
char universe;
|
||||
char winch;
|
||||
short arithrecursion; /* current arithmetic recursion level */
|
||||
char indebug; /* set when in debug trap */
|
||||
unsigned char ignsig; /* ignored signal in subshell */
|
||||
unsigned char lastsig; /* last signal received */
|
||||
char pathinit; /* pathinit called from subshell */
|
||||
char comsub; /* set to 1 when in `...`, 2 when in ${ ...; }, 3 when in $(...) */
|
||||
char subshare; /* set when comsub==2 (shared-state ${ ...; } command substitution) */
|
||||
char toomany; /* set when out of fd's */
|
||||
char instance; /* in set_instance */
|
||||
char decomma; /* decimal_point=',' */
|
||||
char redir0; /* redirect of 0 */
|
||||
char *readscript; /* set before reading a script */
|
||||
int subdup; /* bitmask for dups of 1 */
|
||||
int *inpipe; /* input pipe pointer */
|
||||
int *outpipe; /* output pipe pointer */
|
||||
int cpipe[3];
|
||||
int coutpipe;
|
||||
int inuse_bits;
|
||||
struct argnod *envlist;
|
||||
struct dolnod *arglist;
|
||||
int fn_depth;
|
||||
int fn_reset;
|
||||
int dot_depth;
|
||||
int hist_depth;
|
||||
int xargmin;
|
||||
int xargmax;
|
||||
int xargexit;
|
||||
int nenv;
|
||||
mode_t mask;
|
||||
void *env; /* environment */
|
||||
void *init_context;
|
||||
void *mac_context;
|
||||
void *lex_context;
|
||||
void *arg_context;
|
||||
void *pathlist;
|
||||
void *defpathlist;
|
||||
void *cdpathlist;
|
||||
char **argaddr;
|
||||
void *optlist;
|
||||
struct sh_scoped global;
|
||||
struct checkpt checkbase;
|
||||
Shinit_f userinit;
|
||||
Shbltin_f bltinfun;
|
||||
Shbltin_t bltindata;
|
||||
char *cur_line;
|
||||
int offsets[10];
|
||||
Sfio_t **sftable;
|
||||
unsigned char *fdstatus;
|
||||
const char *pwd;
|
||||
void *jmpbuffer;
|
||||
void *mktype;
|
||||
Sfio_t *strbuf;
|
||||
Sfio_t *strbuf2;
|
||||
Dt_t *first_root;
|
||||
Dt_t *prefix_root;
|
||||
Dt_t *last_root;
|
||||
Dt_t *prev_root;
|
||||
Dt_t *fpathdict;
|
||||
Dt_t *typedict;
|
||||
Dt_t *inpool;
|
||||
char ifstable[256];
|
||||
unsigned long test;
|
||||
Shopt_t offoptions; /* options that were explicitly disabled by the user on the command line */
|
||||
Shopt_t glob_options;
|
||||
Namval_t *typeinit;
|
||||
Namfun_t nvfun;
|
||||
char *mathnodes;
|
||||
char *bltin_dir;
|
||||
struct Regress_s*regress;
|
||||
char exittrap;
|
||||
char errtrap;
|
||||
char end_fn;
|
||||
#if !SHOPT_DEVFD
|
||||
char *fifo; /* FIFO name for current process substitution */
|
||||
Dt_t *fifo_tree; /* for cleaning up process substitution FIFOs */
|
||||
#endif /* !SHOPT_DEVFD */
|
||||
};
|
||||
|
||||
/* used for builtins */
|
||||
|
@ -248,7 +441,6 @@ extern int sh_fchdir(int);
|
|||
extern int sh_fcntl(int, int, ...);
|
||||
extern Sfio_t *sh_fd2sfio(int);
|
||||
extern int (*sh_fdnotify(int(*)(int,int)))(int,int);
|
||||
extern Shell_t *sh_getinterp(void);
|
||||
extern int sh_open(const char*, int, ...);
|
||||
extern int sh_openmax(void);
|
||||
extern Sfio_t *sh_pathopen(const char*);
|
||||
|
@ -268,9 +460,14 @@ extern int sh_waitsafe(void);
|
|||
extern int sh_exec(const Shnode_t*,int);
|
||||
|
||||
/*
|
||||
* direct access to sh is obsolete, use sh_getinterp() instead
|
||||
* As of 93u+m, direct access to sh is no longer obsolete, and
|
||||
* shgd ("global data") is no longer a separately allocated struct;
|
||||
* sh_getinterp() and shgd are provided here for compatibility.
|
||||
*/
|
||||
extern Shell_t sh;
|
||||
extern Shell_t sh;
|
||||
extern Shell_t *sh_getinterp(void); /* for libshell ABI compatibility */
|
||||
#define sh_getinterp() (&sh)
|
||||
#define shgd (&sh)
|
||||
|
||||
#ifdef _DLL
|
||||
# undef extern
|
||||
|
@ -278,7 +475,7 @@ extern Shell_t sh;
|
|||
|
||||
#define chdir(a) sh_chdir(a)
|
||||
#define fchdir(a) sh_fchdir(a)
|
||||
#ifndef _SH_PRIVATE
|
||||
#ifndef defs_h_defined
|
||||
# define access(a,b) sh_access(a,b)
|
||||
# define close(a) sh_close(a)
|
||||
# define exit(a) sh_exit(a)
|
||||
|
@ -295,11 +492,11 @@ extern Shell_t sh;
|
|||
# define open sh_open
|
||||
# define lseek sh_seek
|
||||
# endif
|
||||
#endif /* !_SH_PRIVATE */
|
||||
#endif /* !defs_h_defined */
|
||||
|
||||
#define SH_SIGSET 4
|
||||
#define SH_EXITSIG 0400 /* signal exit bit */
|
||||
#define SH_EXITMASK (SH_EXITSIG-1) /* normal exit status bits */
|
||||
#define SH_RUNPROG -1022 /* needs to be negative and < 256 */
|
||||
|
||||
#endif /* SH_INTERACTIVE */
|
||||
#endif /* !shell_h_defined */
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "timeout.h"
|
||||
|
||||
Shell_t sh = {0};
|
||||
struct shared *shgd;
|
||||
#ifdef __IMPORT__
|
||||
Shell_t *_imp__sh = &sh;
|
||||
#endif
|
||||
|
|
|
@ -1191,7 +1191,7 @@ int sh_type(register const char *path)
|
|||
Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
|
||||
{
|
||||
static int beenhere;
|
||||
Shell_t *shp;
|
||||
Shell_t *shp = &sh;
|
||||
register int n;
|
||||
int type = 0;
|
||||
char *save_envmarker;
|
||||
|
@ -1208,11 +1208,9 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
|
|||
if(!beenhere)
|
||||
{
|
||||
beenhere = 1;
|
||||
shp = &sh;
|
||||
#if SHOPT_REGRESS
|
||||
sh_regress_init(shp);
|
||||
#endif
|
||||
shgd = sh_newof(0,struct shared,1,0);
|
||||
shgd->current_pid = shgd->pid = getpid();
|
||||
shgd->ppid = getppid();
|
||||
shgd->userid=getuid();
|
||||
|
@ -1231,10 +1229,8 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
|
|||
shgd->ed_context = (void*)ed_open(shp);
|
||||
error_info.id = path_basename(argv[0]);
|
||||
}
|
||||
else
|
||||
shp = sh_newof(0,Shell_t,1,0);
|
||||
umask(shp->mask=umask(0));
|
||||
shp->gd = shgd;
|
||||
sh.gd = &sh; /* backwards compatibility pointer (there was formerly a separate global data struct) */
|
||||
shp->mac_context = sh_macopen(shp);
|
||||
shp->arg_context = sh_argopen(shp);
|
||||
shp->lex_context = (void*)sh_lexopen(0,shp,1);
|
||||
|
@ -1487,11 +1483,6 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
|
|||
return(shp);
|
||||
}
|
||||
|
||||
Shell_t *sh_getinterp(void)
|
||||
{
|
||||
return(&sh);
|
||||
}
|
||||
|
||||
/*
|
||||
* reinitialize before executing a script
|
||||
*/
|
||||
|
@ -2124,3 +2115,12 @@ Namfun_t *nv_mapchar(Namval_t *np,const char *name)
|
|||
mp->hdr.disc = &TRANS_disc;
|
||||
return(&mp->hdr);
|
||||
}
|
||||
|
||||
/*
|
||||
* for libshell ABI compatibility
|
||||
*/
|
||||
#undef sh_getinterp
|
||||
Shell_t *sh_getinterp(void)
|
||||
{
|
||||
return(&sh);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue