1 /* $Id: shinstance.h 2657 2012-09-10 20:57:58Z bird $ */
2 /** @file
3  * The shell instance and it's methods.
4  */
5 
6 /*
7  * Copyright (c) 2007-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
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 /**
63  * A child process.
64  */
65 typedef struct shchild
66 {
67     pid_t       pid;                    /**< The pid. */
68 #if K_OS == K_OS_WINDOWS
69     void       *hChild;                 /**< The process handle. */
70 #endif
71 } shchild;
72 
73 /* memalloc.c */
74 #define MINSIZE 504		/* minimum size of a block */
75 struct stack_block {
76 	struct stack_block *prev;
77 	char space[MINSIZE];
78 };
79 
80 /* input.c */
81 struct strpush {
82 	struct strpush *prev;	/* preceding string on stack */
83 	char *prevstring;
84 	int prevnleft;
85 	int prevlleft;
86 	struct alias *ap;	/* if push was associated with an alias */
87 };
88 
89 /*
90  * The parsefile structure pointed to by the global variable parsefile
91  * contains information about the current file being read.
92  */
93 struct parsefile {
94 	struct parsefile *prev;	/* preceding file on stack */
95 	int linno;		/* current line */
96 	int fd;			/* file descriptor (or -1 if string) */
97 	int nleft;		/* number of chars left in this line */
98 	int lleft;		/* number of chars left in this buffer */
99 	char *nextc;		/* next char in buffer */
100 	char *buf;		/* input buffer */
101 	struct strpush *strpush; /* for pushing strings at this level */
102 	struct strpush basestrpush; /* so pushing one is fast */
103 };
104 
105 /* exec.c */
106 #define CMDTABLESIZE 31		/* should be prime */
107 #define ARB 1			/* actual size determined at run time */
108 
109 struct tblentry {
110 	struct tblentry *next;	/* next entry in hash chain */
111 	union param param;	/* definition of builtin function */
112 	short cmdtype;		/* index identifying command */
113 	char rehash;		/* if set, cd done since entry created */
114 	char cmdname[ARB];	/* name of command */
115 };
116 
117 /* expand.c */
118 /*
119  * Structure specifying which parts of the string should be searched
120  * for IFS characters.
121  */
122 struct ifsregion {
123 	struct ifsregion *next;	/* next region in list */
124 	int begoff;		/* offset of start of region */
125 	int endoff;		/* offset of end of region */
126 	int inquotes;		/* search for nul bytes only */
127 };
128 
129 
130 /**
131  * A shell instance.
132  *
133  * This is the core structure of the shell, it contains all
134  * the data associated with a shell process except that it's
135  * running in a thread and not a separate process.
136  */
137 struct shinstance
138 {
139     struct shinstance  *next;           /**< The next shell instance. */
140     struct shinstance  *prev;           /**< The previous shell instance. */
141     struct shinstance  *parent;         /**< The parent shell instance. */
142     pid_t               pid;            /**< The (fake) process id of this shell instance. */
143     shtid               tid;            /**< The thread identifier of the thread for this shell. */
144     shfdtab             fdtab;          /**< The file descriptor table. */
145     shsigaction_t       sigactions[NSIG]; /**< The signal actions registered with this shell instance. */
146     shsigset_t          sigmask;        /**< Our signal mask. */
147     char              **shenviron;      /**< The environment vector. */
148     int                 num_children;   /**< Number of children in the array. */
149     shchild            *children;       /**< The child array. */
150 
151     /* alias.c */
152 #define ATABSIZE 39
153     struct alias       *atab[ATABSIZE];
154 
155     /* cd.c */
156     char               *curdir;         /**< current working directory */
157     char               *prevdir;        /**< previous working directory */
158     char               *cdcomppath;
159     int                 getpwd_first;   /**< static in getpwd. (initialized to 1!) */
160 
161     /* error.h */
162     struct jmploc      *handler;
163     int                 exception;
164     int                 exerrno/* = 0 */; /**< Last exec error */
165     int volatile        suppressint;
166     int volatile        intpending;
167 
168     /* error.c */
169     char                errmsg_buf[16]; /**< static in errmsg. (bss) */
170 
171     /* eval.h */
172     char               *commandname;    /**< currently executing command */
173     int                 exitstatus;     /**< exit status of last command */
174     int                 back_exitstatus;/**< exit status of backquoted command */
175     struct strlist     *cmdenviron;     /**< environment for builtin command */
176     int                 funcnest;       /**< depth of function calls */
177     int                 evalskip;       /**< set if we are skipping commands */
178     int                 skipcount;      /**< number of levels to skip */
179     int                 loopnest;       /**< current loop nesting level */
180 
181     /* eval.c */
182     int                 vforked;
183 
184     /* expand.c */
185     char               *expdest;        /**< output of current string */
186     struct nodelist    *argbackq;       /**< list of back quote expressions */
187     struct ifsregion    ifsfirst;       /**< first struct in list of ifs regions */
188     struct ifsregion   *ifslastp;       /**< last struct in list */
189     struct arglist      exparg;         /**< holds expanded arg list */
190     char               *expdir;         /**< Used by expandmeta. */
191 
192     /* exec.h */
193     const char         *pathopt;        /**< set by padvance */
194 
195     /* exec.c */
196     struct tblentry    *cmdtable[CMDTABLESIZE];
197     int                 builtinloc/* = -1*/;    /**< index in path of %builtin, or -1 */
198 
199     /* input.h */
200     int                 plinno/* = 1 */;/**< input line number */
201     int                 parsenleft;     /**< number of characters left in input buffer */
202     char               *parsenextc;     /**< next character in input buffer */
203     int                 init_editline/* = 0 */;     /**< 0 == not setup, 1 == OK, -1 == failed */
204 
205     /* input.c */
206     int                 parselleft;     /**< copy of parsefile->lleft */
207     struct parsefile    basepf;         /**< top level input file */
208     char                basebuf[BUFSIZ];/**< buffer for top level input file */
209     struct parsefile   *parsefile/* = &basepf*/;    /**< current input file */
210 #ifndef SMALL
211     EditLine           *el;             /**< cookie for editline package */
212 #endif
213 
214     /* jobs.h */
215     pid_t               backgndpid/* = -1 */;   /**< pid of last background process */
216     int                 job_warning;    /**< user was warned about stopped jobs */
217 
218     /* jobs.c */
219     struct job         *jobtab;         /**< array of jobs */
220     int                 njobs;          /**< size of array */
221     int                 jobs_invalid;   /**< set in child */
222     int                 initialpgrp;    /**< pgrp of shell on invocation */
223     int                 curjob/* = -1*/;/**< current job */
224     int                 ttyfd/* = -1*/;
225     int                 jobctl;         /**< job control enabled / disabled */
226     char               *cmdnextc;
227     int                 cmdnleft;
228 
229 
230     /* mail.c */
231 #define MAXMBOXES 10
232     int                 nmboxes;        /**< number of mailboxes */
233     time_t              mailtime[MAXMBOXES]; /**< times of mailboxes */
234 
235     /* main.h */
236     int                 rootpid;        /**< pid of main shell. */
237     int                 rootshell;      /**< true if we aren't a child of the main shell. */
238     struct shinstance  *psh_rootshell;  /**< The root shell pointer. (!rootshell) */
239 
240     /* memalloc.h */
241     char               *stacknxt/* = stackbase.space*/;
242     int                 stacknleft/* = MINSIZE*/;
243     int                 sstrnleft;
244     int                 herefd/* = -1 */;
245 
246     /* memalloc.c */
247     struct stack_block  stackbase;
248     struct stack_block *stackp/* = &stackbase*/;
249     struct stackmark   *markp;
250 
251     /* myhistedit.h */
252     int                 displayhist;
253 #ifndef SMALL
254     History            *hist;
255     EditLine           *el;
256 #endif
257 
258     /* output.h */
259     struct output       output;
260     struct output       errout;
261     struct output       memout;
262     struct output      *out1;
263     struct output      *out2;
264 
265     /* output.c */
266 #define OUTBUFSIZ BUFSIZ
267 #define MEM_OUT -3                      /**< output to dynamically allocated memory */
268 
269     /* options.h */
270     struct optent       optlist[NOPTS];
271     char               *minusc;         /**< argument to -c option */
272     char               *arg0;           /**< $0 */
273     struct shparam      shellparam;     /**< $@ */
274     char              **argptr;         /**< argument list for builtin commands */
275     char               *optionarg;      /**< set by nextopt */
276     char               *optptr;         /**< used by nextopt */
277 
278     /* parse.h */
279     int                 tokpushback;
280     int                 whichprompt;    /**< 1 == PS1, 2 == PS2 */
281 
282     /* parser.c */
283     int                 noalias/* = 0*/;/**< when set, don't handle aliases */
284     struct heredoc     *heredoclist;    /**< list of here documents to read */
285     int                 parsebackquote; /**< nonzero if we are inside backquotes */
286     int                 doprompt;       /**< if set, prompt the user */
287     int                 needprompt;     /**< true if interactive and at start of line */
288     int                 lasttoken;      /**< last token read */
289     char               *wordtext;       /**< text of last word returned by readtoken */
290     int                 checkkwd;       /**< 1 == check for kwds, 2 == also eat newlines */
291     struct nodelist    *backquotelist;
292     union node         *redirnode;
293     struct heredoc     *heredoc;
294     int                 quoteflag;      /**< set if (part of) last token was quoted */
295     int                 startlinno;     /**< line # where last token started */
296 
297     /* redir.c */
298     struct redirtab    *redirlist;
299     int                 fd0_redirected/* = 0*/;
300 
301     /* show.c */
302     char                tracebuf[1024];
303     size_t              tracepos;
304     int                 tracefd;
305 
306     /* trap.h */
307     int                 pendingsigs;    /**< indicates some signal received */
308 
309     /* trap.c */
310     char                gotsig[NSIG];   /**< indicates specified signal received */
311     char               *trap[NSIG+1];   /**< trap handler commands */
312     char                sigmode[NSIG];  /**< current value of signal */
313 
314     /* var.h */
315     struct localvar    *localvars;
316     struct var          vatty;
317     struct var          vifs;
318     struct var          vmail;
319     struct var          vmpath;
320     struct var          vpath;
321 #ifdef _MSC_VER
322     struct var          vpath2;
323 #endif
324     struct var          vps1;
325     struct var          vps2;
326     struct var          vps4;
327 #ifndef SMALL
328     struct var          vterm;
329     struct var          vhistsize;
330 #endif
331     struct var          voptind;
332 #ifdef PC_OS2_LIBPATHS
333     struct var          libpath_vars[4];
334 #endif
335 #ifdef SMALL
336 # define VTABSIZE 39
337 #else
338 # define VTABSIZE 517
339 #endif
340     struct var         *vartab[VTABSIZE];
341 
342     /* builtins.h */
343 
344     /* bltin/test.c */
345     char              **t_wp;
346     struct t_op const  *t_wp_op;
347 
348 };
349 
350 
351 extern shinstance *sh_create_root_shell(shinstance *, int, char **, char **);
352 
353 /* environment & pwd.h */
354 char *sh_getenv(shinstance *, const char *);
355 char **sh_environ(shinstance *);
356 const char *sh_gethomedir(shinstance *, const char *);
357 
358 /* signals */
359 #define SH_SIG_UNK ((shsig_t)(intptr_t)-199)
360 #define SH_SIG_DFL ((shsig_t)SIG_DFL)
361 #define SH_SIG_IGN ((shsig_t)SIG_IGN)
362 #define SH_SIG_ERR ((shsig_t)SIG_ERR)
363 #ifdef _MSC_VER
364 #   define SA_RESTART       0x02
365 #   define SIG_BLOCK         1
366 #   define SIG_UNBLOCK       2
367 #   define SIG_SETMASK       3
368 
369 #   define SIGHUP            1          /* _SIGHUP_IGNORE */
370 /*# define SIGINT            2 */
371 #   define SIGQUIT           3          /* _SIGQUIT_IGNORE */
372 /*# define SIGILL            4 */
373 /*# define SIGFPE            8 */
374 /*# define SIGSEGV          11 */
375 #   define SIGPIPE          13          /* _SIGPIPE_IGNORE */
376 /*# define SIGTERM          15 */
377 #   define SIGTTIN          16          /* _SIGIOINT_IGNORE */
378 #   define SIGTSTP          17          /* _SIGSTOP_IGNORE */
379 #   define SIGTTOU          18
380 #   define SIGCONT          20
381 /*# define SIGBREAK         21 */
382 /*# define SIGABRT          22 */
383 
384 #   define sys_siglist      sys_signame
385 #endif /* _MSC_VER */
386 #ifdef __sun__
387 #   define sys_siglist      _sys_siglist
388 #endif
389 #ifndef HAVE_SYS_SIGNAME
390 extern char sys_signame[NSIG][16];
391 #endif
392 
393 int sh_sigaction(shinstance *, int, const struct shsigaction *, struct shsigaction *);
394 shsig_t sh_signal(shinstance *, int, shsig_t);
395 int sh_siginterrupt(shinstance *, int, int);
396 void sh_sigemptyset(shsigset_t *);
397 void sh_sigfillset(shsigset_t *);
398 void sh_sigaddset(shsigset_t *, int);
399 void sh_sigdelset(shsigset_t *, int);
400 int sh_sigismember(shsigset_t const *, int);
401 int sh_sigprocmask(shinstance *, int, shsigset_t const *, shsigset_t *);
402 SH_NORETURN_1 void sh_abort(shinstance *) SH_NORETURN_2;
403 void sh_raise_sigint(shinstance *);
404 int sh_kill(shinstance *, pid_t, int);
405 int sh_killpg(shinstance *, pid_t, int);
406 
407 /* times */
408 #include <time.h>
409 #ifdef _MSC_VER
410     typedef struct shtms
411     {
412         clock_t tms_utime;
413         clock_t tms_stime;
414         clock_t tms_cutime;
415         clock_t tms_cstime;
416     } shtms;
417 #else
418 #   include <sys/times.h>
419     typedef struct tms shtms;
420 #endif
421 clock_t sh_times(shinstance *, shtms *);
422 int sh_sysconf_clk_tck(void);
423 
424 /* wait / process */
425 int sh_add_child(shinstance *psh, pid_t pid, void *hChild);
426 #ifdef _MSC_VER
427 #   include <process.h>
428 #   define WNOHANG         1       /* Don't hang in wait. */
429 #   define WUNTRACED       2       /* Tell about stopped, untraced children. */
430 #   define WCONTINUED      4       /* Report a job control continued process. */
431 #   define _W_INT(w)       (*(int *)&(w))  /* Convert union wait to int. */
432 #   define WCOREFLAG       0200
433 #   define _WSTATUS(x)     (_W_INT(x) & 0177)
434 #   define _WSTOPPED       0177            /* _WSTATUS if process is stopped */
435 #   define WIFSTOPPED(x)   (_WSTATUS(x) == _WSTOPPED)
436 #   define WSTOPSIG(x)     (_W_INT(x) >> 8)
437 #   define WIFSIGNALED(x)  (_WSTATUS(x) != 0 && !WIFSTOPPED(x) && !WIFCONTINUED(x)) /* bird: made GLIBC tests happy. */
438 #   define WTERMSIG(x)     (_WSTATUS(x))
439 #   define WIFEXITED(x)    (_WSTATUS(x) == 0)
440 #   define WEXITSTATUS(x)  (_W_INT(x) >> 8)
441 #   define WIFCONTINUED(x) (x == 0x13)     /* 0x13 == SIGCONT */
442 #   define WCOREDUMP(x)    (_W_INT(x) & WCOREFLAG)
443 #   define W_EXITCODE(ret, sig)    ((ret) << 8 | (sig))
444 #   define W_STOPCODE(sig)         ((sig) << 8 | _WSTOPPED)
445 #else
446 #   include <sys/wait.h>
447 #   ifdef __HAIKU__
448 #       define WCOREDUMP(x) WIFCORED(x)
449 #   endif
450 #endif
451 pid_t sh_fork(shinstance *);
452 pid_t sh_waitpid(shinstance *, pid_t, int *, int);
453 SH_NORETURN_1 void sh__exit(shinstance *, int) SH_NORETURN_2;
454 int sh_execve(shinstance *, const char *, const char * const*, const char * const *);
455 uid_t sh_getuid(shinstance *);
456 uid_t sh_geteuid(shinstance *);
457 gid_t sh_getgid(shinstance *);
458 gid_t sh_getegid(shinstance *);
459 pid_t sh_getpid(shinstance *);
460 pid_t sh_getpgrp(shinstance *);
461 pid_t sh_getpgid(shinstance *, pid_t);
462 int sh_setpgid(shinstance *, pid_t, pid_t);
463 
464 /* tc* */
465 pid_t sh_tcgetpgrp(shinstance *, int);
466 int sh_tcsetpgrp(shinstance *, int, pid_t);
467 
468 /* sys/resource.h */
469 #ifdef _MSC_VER
470     typedef int64_t shrlim_t;
471     typedef struct shrlimit
472     {
473         shrlim_t   rlim_cur;
474         shrlim_t   rlim_max;
475     } shrlimit;
476 #   define RLIMIT_CPU     0
477 #   define RLIMIT_FSIZE   1
478 #   define RLIMIT_DATA    2
479 #   define RLIMIT_STACK   3
480 #   define RLIMIT_CORE    4
481 #   define RLIMIT_RSS     5
482 #   define RLIMIT_MEMLOCK 6
483 #   define RLIMIT_NPROC   7
484 #   define RLIMIT_NOFILE  8
485 #   define RLIMIT_SBSIZE  9
486 #   define RLIMIT_VMEM    10
487 #   define RLIM_NLIMITS   11
488 #   define RLIM_INFINITY  (0x7fffffffffffffffLL)
489 #else
490     typedef rlim_t          shrlim_t;
491     typedef struct rlimit   shrlimit;
492 #endif
493 int sh_getrlimit(shinstance *, int, shrlimit *);
494 int sh_setrlimit(shinstance *, int, const shrlimit *);
495 
496 /* string.h */
497 const char *sh_strerror(shinstance *, int);
498 
499 #ifdef DEBUG
500 # define TRACE2(param)	trace param
501 # define TRACE2V(param)	tracev param
502 #else
503 # define TRACE2(param)  do { } while (0)
504 # define TRACE2V(param) do { } while (0)
505 #endif
506 
507 #endif
508