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