VirtualBox

source: kBuild/trunk/src/kash/shinstance.h@ 3468

Last change on this file since 3468 was 3468, checked in by bird, 4 years ago

kash: Need to initialize mutexes on windows after forking now that we've finally got real mutexes.

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
File size: 21.5 KB
Line 
1/* $Id: shinstance.h 3468 2020-09-15 23:28:47Z bird $ */
2/** @file
3 * The shell instance and it's methods.
4 */
5
6/*
7 * Copyright (c) 2007-2010 knut st. osmundsen <[email protected]>
8 *
9 *
10 * This file is part of kBuild.
11 *
12 * kBuild is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * kBuild is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with kBuild; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#ifndef ___shinstance_h
29#define ___shinstance_h
30
31#include <stdio.h> /* BUFSIZ */
32#include <signal.h> /* NSIG */
33#ifndef _MSC_VER
34# include <termios.h>
35# include <sys/types.h>
36# include <sys/ioctl.h>
37# include <sys/resource.h>
38#endif
39#include <errno.h>
40#ifdef _MSC_VER
41# define EWOULDBLOCK 140
42#endif
43
44#include "shtypes.h"
45#include "shthread.h"
46#include "shfile.h"
47#include "shheap.h"
48#include "shell.h"
49#include "output.h"
50#include "options.h"
51
52#include "expand.h"
53#include "exec.h"
54#include "var.h"
55#include "show.h"
56
57#ifdef _MSC_VER
58# define strcasecmp stricmp
59# define strncasecmp strnicmp
60#endif
61
62#ifndef SH_FORKED_MODE
63extern shmtx g_sh_exec_inherit_mtx;
64#endif
65
66#ifndef SH_FORKED_MODE
67/**
68 * Subshell status.
69 */
70typedef struct shsubshellstatus
71{
72 unsigned volatile refs; /**< Reference counter. */
73 int volatile status; /**< The exit code. */
74 KBOOL volatile done; /**< Set if done (valid exit code). */
75 void *towaiton; /**< Event semaphore / whatever to wait on. */
76# if K_OS == K_OS_WINDOWS
77 uintptr_t volatile hThread; /**< The thread handle (child closes this). */
78# endif
79 struct shsubshellstatus *next; /**< Next free one on the free chain. */
80} shsubshellstatus;
81#endif
82
83/**
84 * A child process.
85 */
86typedef struct shchild
87{
88 shpid pid; /**< The pid. */
89#if K_OS == K_OS_WINDOWS
90 void *hChild; /**< The handle to wait on. */
91#endif
92#ifndef SH_FORKED_MODE
93 shsubshellstatus *subshellstatus; /**< Pointer to the subshell status structure. NULL if child process. */
94#endif
95} shchild;
96
97/* memalloc.c */
98#define MINSIZE 504 /* minimum size of a block */
99struct stack_block {
100 struct stack_block *prev;
101 char space[MINSIZE];
102};
103
104#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
105/** Parser stack allocator block.
106 * These are reference counted so they can be shared between the parent and
107 * child shells. They are also using as an alternative to copying function
108 * definitions, here the final goal is to automatically emit separate
109 * pstack_blocks for function while parsing to make it more flexible. */
110typedef struct pstack_block {
111 /** Pointer to the next unallocated byte (= stacknxt). */
112 char *nextbyte;
113 /** Number of bytes available in the current stack block (= stacknleft). */
114 size_t avail;
115 /* Number of chars left for string data (PSTPUTC, PSTUPUTC, et al) (= sstrnleft). */
116 size_t strleft;
117 /** Top of the allocation stack (nextbyte points within this). */
118 struct stack_block *top;
119 /** Size of the top stack element (user space only). */
120 size_t topsize;
121 /** @name statistics
122 * @{ */
123 size_t allocations;
124 size_t bytesalloced;
125 size_t nodesalloced;
126 size_t entriesalloced;
127 size_t strbytesalloced;
128 size_t blocks;
129 size_t fragmentation;
130 /** @} */
131 /** Reference counter. */
132 unsigned volatile refs;
133 /** Whether to make it current when is restored to the top of the stack. */
134 KBOOL done;
135 /** The first stack block. */
136 struct stack_block first;
137} pstack_block;
138#endif
139
140/* input.c */
141struct strpush {
142 struct strpush *prev; /* preceding string on stack */
143 char *prevstring;
144 int prevnleft;
145 int prevlleft;
146 struct alias *ap; /* if push was associated with an alias */
147};
148
149/*
150 * The parsefile structure pointed to by the global variable parsefile
151 * contains information about the current file being read.
152 */
153struct parsefile {
154 struct parsefile *prev; /* preceding file on stack */
155 int linno; /* current line */
156 int fd; /* file descriptor (or -1 if string) */
157 int nleft; /* number of chars left in this line */
158 int lleft; /* number of chars left in this buffer */
159 char *nextc; /* next char in buffer */
160 char *buf; /* input buffer */
161 struct strpush *strpush; /* for pushing strings at this level */
162 struct strpush basestrpush; /* so pushing one is fast */
163};
164
165/* exec.c */
166#define CMDTABLESIZE 31 /* should be prime */
167#define ARB 1 /* actual size determined at run time */
168
169struct tblentry {
170 struct tblentry *next; /* next entry in hash chain */
171 union param param; /* definition of builtin function */
172 short cmdtype; /* index identifying command */
173 char rehash; /* if set, cd done since entry created */
174 char cmdname[ARB]; /* name of command */
175};
176
177/* expand.c */
178/*
179 * Structure specifying which parts of the string should be searched
180 * for IFS characters.
181 */
182struct ifsregion {
183 struct ifsregion *next; /* next region in list */
184 int begoff; /* offset of start of region */
185 int endoff; /* offset of end of region */
186 int inquotes; /* search for nul bytes only */
187};
188
189/* redir.c */
190struct redirtab {
191 struct redirtab *next;
192 short renamed[10];
193};
194
195/**
196 * This is a replacement for temporary node field nfile.expfname.
197 * Uses stack allocator, created by expredir(), duplicated by
198 * subshellinitredir() and popped (but not freed) by expredircleanup().
199 */
200typedef struct redirexpfnames
201{
202 struct redirexpfnames *prev; /**< Previous record. */
203 unsigned depth; /**< Nesting depth. */
204 unsigned count; /**< Number of expanded filenames in the array. */
205 char *names[1]; /**< Variable size. */
206} redirexpfnames;
207
208
209/**
210 * A shell instance.
211 *
212 * This is the core structure of the shell, it contains all
213 * the data associated with a shell process except that it's
214 * running in a thread and not a separate process.
215 */
216struct shinstance
217{
218 struct shinstance *next; /**< The next shell instance. */
219 struct shinstance *prev; /**< The previous shell instance. */
220 struct shinstance *parent; /**< The parent shell instance. */
221 shpid pid; /**< The (fake) process id of this shell instance. */
222 shtid tid; /**< The thread identifier of the thread for this shell. */
223 shpid pgid; /**< Process group ID. */
224 shfdtab fdtab; /**< The file descriptor table. */
225 shsigaction_t sigactions[NSIG]; /**< The signal actions registered with this shell instance. */
226 shsigset_t sigmask; /**< Our signal mask. */
227 char **shenviron; /**< The environment vector. */
228 int linked; /**< Set if we're still linked. */
229 unsigned num_children; /**< Number of children in the array. */
230 shchild *children; /**< The child array. */
231#ifndef SH_FORKED_MODE
232 int (*thread)(struct shinstance *, void *); /**< The thread procedure. */
233 void *threadarg; /**< The thread argument. */
234 struct jmploc *exitjmp; /**< Long jump target in sh_thread_wrapper for use by sh__exit. */
235 shsubshellstatus *subshellstatus; /**< Pointer to the subshell status structure (NULL if root). */
236#endif
237
238 /* alias.c */
239#define ATABSIZE 39
240 struct alias *atab[ATABSIZE];
241 unsigned aliases; /**< Number of active aliases. */
242
243 /* cd.c */
244 char *curdir; /**< current working directory */
245 char *prevdir; /**< previous working directory */
246 char *cdcomppath; /**< (stalloc) */
247 int getpwd_first; /**< static in getpwd. (initialized to 1!) */
248
249 /* error.h */
250 struct jmploc *handler;
251 int exception;
252 int exerrno/* = 0 */; /**< Last exec error */
253 int volatile suppressint;
254 int volatile intpending;
255
256 /* error.c */
257 char errmsg_buf[16]; /**< static in errmsg. (bss) */
258
259 /* eval.h */
260 char *commandname; /**< currently executing command */
261 int exitstatus; /**< exit status of last command */
262 int back_exitstatus;/**< exit status of backquoted command */
263 struct strlist *cmdenviron; /**< environment for builtin command (varlist from evalcommand()) */
264 int funcnest; /**< depth of function calls */
265 int evalskip; /**< set if we are skipping commands */
266 int skipcount; /**< number of levels to skip */
267 int loopnest; /**< current loop nesting level */
268 int commandnamemalloc; /**< Set if commandname is malloc'ed (only subshells). */
269
270 /* expand.c */
271 char *expdest; /**< output of current string (stack) */
272 struct nodelist *argbackq; /**< list of back quote expressions */
273 struct ifsregion ifsfirst; /**< first struct in list of ifs regions */
274 struct ifsregion *ifslastp; /**< last struct in list */
275 struct arglist exparg; /**< holds expanded arg list (stack) */
276 char *expdir; /**< Used by expandmeta. */
277
278 /* exec.h */
279 const char *pathopt; /**< set by padvance */
280
281 /* exec.c */
282 struct tblentry *cmdtable[CMDTABLESIZE];
283 int builtinloc/* = -1*/; /**< index in path of %builtin, or -1 */
284
285 /* input.h */
286 int plinno/* = 1 */;/**< input line number */
287 int parsenleft; /**< number of characters left in input buffer */
288 char *parsenextc; /**< next character in input buffer */
289 int init_editline/* = 0 */; /**< 0 == not setup, 1 == OK, -1 == failed */
290
291 /* input.c */
292 int parselleft; /**< copy of parsefile->lleft */
293 struct parsefile basepf; /**< top level input file */
294 char basebuf[BUFSIZ];/**< buffer for top level input file */
295 struct parsefile *parsefile/* = &basepf*/; /**< current input file */
296#ifndef SMALL
297 EditLine *el; /**< cookie for editline package */
298#endif
299
300 /* jobs.h */
301 shpid backgndpid/* = -1 */; /**< pid of last background process */
302 int job_warning; /**< user was warned about stopped jobs */
303
304 /* jobs.c */
305 struct job *jobtab; /**< array of jobs */
306 int njobs; /**< size of array */
307 int jobs_invalid; /**< set in child */
308 shpid initialpgrp; /**< pgrp of shell on invocation */
309 int curjob/* = -1*/;/**< current job */
310 int ttyfd/* = -1*/;
311 int jobctl; /**< job control enabled / disabled */
312 char *cmdnextc;
313 int cmdnleft;
314
315
316 /* mail.c */
317#define MAXMBOXES 10
318 int nmboxes; /**< number of mailboxes */
319 time_t mailtime[MAXMBOXES]; /**< times of mailboxes */
320
321 /* main.h */
322 shpid rootpid; /**< pid of main shell. */
323 int rootshell; /**< true if we aren't a child of the main shell. */
324 struct shinstance *psh_rootshell; /**< The root shell pointer. (!rootshell) */
325
326 /* memalloc.h */
327 char *stacknxt/* = stackbase.space*/;
328 int stacknleft/* = MINSIZE*/;
329 int sstrnleft;
330 int herefd/* = -1 */;
331
332 /* memalloc.c */
333 struct stack_block stackbase;
334 struct stack_block *stackp/* = &stackbase*/;
335 struct stackmark *markp;
336
337#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
338 pstack_block *curpstack; /**< The pstack entry we're currently allocating from (NULL when not in parse.c). */
339 pstack_block **pstack; /**< Stack of parsed stuff. */
340 unsigned pstacksize; /**< Number of entries in pstack. */
341 unsigned pstackalloced; /**< The allocated size of pstack. */
342 pstack_block *freepstack; /**< One cached pstack entry (lots of parsecmd calls). */
343#endif
344
345 /* myhistedit.h */
346 int displayhist;
347#ifndef SMALL
348 History *hist;
349 EditLine *el;
350#endif
351
352 /* output.h */
353 struct output output;
354 struct output errout;
355 struct output memout;
356 struct output *out1;
357 struct output *out2;
358
359 /* output.c */
360#define OUTBUFSIZ BUFSIZ
361#define MEM_OUT -3 /**< output to dynamically allocated memory */
362
363 /* options.h */
364 struct optent optlist[NOPTS];
365 char *minusc; /**< argument to -c option */
366 char *arg0; /**< $0 */
367 struct shparam shellparam; /**< $@ */
368 char **argptr; /**< argument list for builtin commands */
369 char *optionarg; /**< set by nextopt */
370 char *optptr; /**< used by nextopt */
371 char **orgargv; /**< The original argument vector (for cleanup). */
372 int arg0malloc; /**< Indicates whether arg0 was allocated or is part of orgargv. */
373
374 /* parse.h */
375 int tokpushback;
376 int whichprompt; /**< 1 == PS1, 2 == PS2 */
377
378 /* parser.c */
379 int noalias/* = 0*/;/**< when set, don't handle aliases */
380 struct heredoc *heredoclist; /**< list of here documents to read */
381 int parsebackquote; /**< nonzero if we are inside backquotes */
382 int doprompt; /**< if set, prompt the user */
383 int needprompt; /**< true if interactive and at start of line */
384 int lasttoken; /**< last token read */
385 char *wordtext; /**< text of last word returned by readtoken */
386 int checkkwd; /**< 1 == check for kwds, 2 == also eat newlines */
387 struct nodelist *backquotelist;
388 union node *redirnode;
389 struct heredoc *heredoc;
390 int quoteflag; /**< set if (part of) last token was quoted */
391 int startlinno; /**< line # where last token started */
392
393 /* redir.c */
394 struct redirtab *redirlist;
395 int fd0_redirected/* = 0*/;
396 redirexpfnames *expfnames; /**< Expanded filenames for current redirection setup. */
397
398 /* show.c */
399 char tracebuf[1024];
400 size_t tracepos;
401 int tracefd;
402
403 /* trap.h */
404 int pendingsigs; /**< indicates some signal received */
405
406 /* trap.c */
407 char gotsig[NSIG]; /**< indicates specified signal received */
408 char *trap[NSIG+1]; /**< trap handler commands */
409 char sigmode[NSIG]; /**< current value of signal */
410
411 /* var.h */
412 struct localvar *localvars;
413 struct var vatty;
414 struct var vifs;
415 struct var vmail;
416 struct var vmpath;
417 struct var vpath;
418#ifdef _MSC_VER
419 struct var vpath2;
420#endif
421 struct var vps1;
422 struct var vps2;
423 struct var vps4;
424#ifndef SMALL
425 struct var vterm;
426 struct var vhistsize;
427#endif
428 struct var voptind;
429#ifdef PC_OS2_LIBPATHS
430 struct var libpath_vars[4];
431#endif
432#ifdef SMALL
433# define VTABSIZE 39
434#else
435# define VTABSIZE 517
436#endif
437 struct var *vartab[VTABSIZE];
438
439 /* builtins.h */
440
441 /* bltin/test.c */
442 char **t_wp;
443 struct t_op const *t_wp_op;
444};
445
446extern void sh_init_globals(void);
447extern shinstance *sh_create_root_shell(char **, char **);
448extern shinstance *sh_create_child_shell(shinstance *);
449
450/* environment & pwd.h */
451char *sh_getenv(shinstance *, const char *);
452char **sh_environ(shinstance *);
453const char *sh_gethomedir(shinstance *, const char *);
454
455/* signals */
456#define SH_SIG_UNK ((shsig_t)(intptr_t)-199)
457#define SH_SIG_DFL ((shsig_t)(intptr_t)SIG_DFL)
458#define SH_SIG_IGN ((shsig_t)(intptr_t)SIG_IGN)
459#define SH_SIG_ERR ((shsig_t)(intptr_t)SIG_ERR)
460#ifdef _MSC_VER
461# define SA_RESTART 0x02
462# define SIG_BLOCK 1
463# define SIG_UNBLOCK 2
464# define SIG_SETMASK 3
465
466# define SIGHUP 1 /* _SIGHUP_IGNORE */
467/*# define SIGINT 2 */
468# define SIGQUIT 3 /* _SIGQUIT_IGNORE */
469/*# define SIGILL 4 */
470/*# define SIGFPE 8 */
471/*# define SIGSEGV 11 */
472# define SIGPIPE 13 /* _SIGPIPE_IGNORE */
473/*# define SIGTERM 15 */
474# define SIGTTIN 16 /* _SIGIOINT_IGNORE */
475# define SIGTSTP 17 /* _SIGSTOP_IGNORE */
476# define SIGTTOU 18
477# define SIGCONT 20
478/*# define SIGBREAK 21 */
479/*# define SIGABRT 22 */
480const char *strsignal(int iSig);
481#endif /* _MSC_VER */
482#ifndef HAVE_SYS_SIGNAME
483extern const char * const sys_signame[NSIG];
484#endif
485
486int sh_sigaction(shinstance *, int, const struct shsigaction *, struct shsigaction *);
487shsig_t sh_signal(shinstance *, int, shsig_t);
488int sh_siginterrupt(shinstance *, int, int);
489void sh_sigemptyset(shsigset_t *);
490void sh_sigfillset(shsigset_t *);
491void sh_sigaddset(shsigset_t *, int);
492void sh_sigdelset(shsigset_t *, int);
493int sh_sigismember(shsigset_t const *, int);
494int sh_sigprocmask(shinstance *, int, shsigset_t const *, shsigset_t *);
495SH_NORETURN_1 void sh_abort(shinstance *) SH_NORETURN_2;
496void sh_raise_sigint(shinstance *);
497int sh_kill(shinstance *, shpid, int);
498int sh_killpg(shinstance *, shpid, int);
499
500/* times */
501#include <time.h>
502#ifdef _MSC_VER
503 typedef struct shtms
504 {
505 clock_t tms_utime;
506 clock_t tms_stime;
507 clock_t tms_cutime;
508 clock_t tms_cstime;
509 } shtms;
510#else
511# include <sys/times.h>
512 typedef struct tms shtms;
513#endif
514clock_t sh_times(shinstance *, shtms *);
515int sh_sysconf_clk_tck(void);
516
517/* wait / process */
518int sh_add_child(shinstance *psh, shpid pid, void *hChild, struct shsubshellstatus *sts);
519#ifdef _MSC_VER
520# include <process.h>
521# define WNOHANG 1 /* Don't hang in wait. */
522# define WUNTRACED 2 /* Tell about stopped, untraced children. */
523# define WCONTINUED 4 /* Report a job control continued process. */
524# define _W_INT(w) (*(int *)&(w)) /* Convert union wait to int. */
525# define WCOREFLAG 0200
526# define _WSTATUS(x) (_W_INT(x) & 0177)
527# define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
528# define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
529# define WSTOPSIG(x) (_W_INT(x) >> 8)
530# define WIFSIGNALED(x) (_WSTATUS(x) != 0 && !WIFSTOPPED(x) && !WIFCONTINUED(x)) /* bird: made GLIBC tests happy. */
531# define WTERMSIG(x) (_WSTATUS(x))
532# define WIFEXITED(x) (_WSTATUS(x) == 0)
533# define WEXITSTATUS(x) (_W_INT(x) >> 8)
534# define WIFCONTINUED(x) (x == 0x13) /* 0x13 == SIGCONT */
535# define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
536# define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
537# define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
538#else
539# include <sys/wait.h>
540# ifdef __HAIKU__
541# define WCOREDUMP(x) WIFCORED(x)
542# endif
543#endif
544#ifdef SH_FORKED_MODE
545shpid sh_fork(shinstance *);
546#else
547shpid sh_thread_start(shinstance *pshparent, shinstance *pshchild, int (*thread)(shinstance *, void *), void *arg);
548#endif
549shpid sh_waitpid(shinstance *, shpid, int *, int);
550SH_NORETURN_1 void sh__exit(shinstance *, int) SH_NORETURN_2;
551int sh_execve(shinstance *, const char *, const char * const*, const char * const *);
552uid_t sh_getuid(shinstance *);
553uid_t sh_geteuid(shinstance *);
554gid_t sh_getgid(shinstance *);
555gid_t sh_getegid(shinstance *);
556shpid sh_getpid(shinstance *);
557shpid sh_getpgrp(shinstance *);
558shpid sh_getpgid(shinstance *, shpid);
559int sh_setpgid(shinstance *, shpid, shpid);
560
561/* tc* */
562shpid sh_tcgetpgrp(shinstance *, int);
563int sh_tcsetpgrp(shinstance *, int, shpid);
564
565/* sys/resource.h */
566#ifdef _MSC_VER
567 typedef int64_t shrlim_t;
568 typedef struct shrlimit
569 {
570 shrlim_t rlim_cur;
571 shrlim_t rlim_max;
572 } shrlimit;
573# define RLIMIT_CPU 0
574# define RLIMIT_FSIZE 1
575# define RLIMIT_DATA 2
576# define RLIMIT_STACK 3
577# define RLIMIT_CORE 4
578# define RLIMIT_RSS 5
579# define RLIMIT_MEMLOCK 6
580# define RLIMIT_NPROC 7
581# define RLIMIT_NOFILE 8
582# define RLIMIT_SBSIZE 9
583# define RLIMIT_VMEM 10
584# define RLIM_NLIMITS 11
585# define RLIM_INFINITY (0x7fffffffffffffffLL)
586#else
587 typedef rlim_t shrlim_t;
588 typedef struct rlimit shrlimit;
589#endif
590int sh_getrlimit(shinstance *, int, shrlimit *);
591int sh_setrlimit(shinstance *, int, const shrlimit *);
592
593/* string.h */
594const char *sh_strerror(shinstance *, int);
595
596#ifdef DEBUG
597# define TRACE2(param) trace param
598# define TRACE2V(param) tracev param
599#else
600# define TRACE2(param) do { } while (0)
601# define TRACE2V(param) do { } while (0)
602#endif
603
604#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette