/* * Do macro expansion in a row of tokens. * Flag is NULL if more input can be gathered. */ void expandrow(Tokenrow *trp, char *flag) { Token *tp; Nlist *np; if (flag) setsource(flag, NULL, ""); for (tp = trp->tp; tp<trp->lp; ) { if (tp->type!=NAME || quicklook(tp->t[0], tp->len>1?tp->t[1]:0)==0 || (np = lookup(tp, 0))==NULL || (np->flag&(ISDEFINED|ISMAC))==0 || tp->hideset && checkhideset(tp->hideset, np)) { tp++; continue; } trp->tp = tp; if (np->val==KDEFINED) { tp->type = DEFINED; if ((tp+1)<trp->lp && (tp+1)->type==NAME) (tp+1)->type = NAME1; else if ((tp+3)<trp->lp && (tp+1)->type==LP && (tp+2)->type==NAME && (tp+3)->type==RP) (tp+2)->type = NAME1; else error(ERROR, "Incorrect syntax for `defined'"); tp++; continue; } if (np->flag&ISMAC) builtin(trp, np->val); else { expand(trp, np); } tp = trp->tp; } if (flag) unsetsource(); }
void ft_launch_exec(char *command, char ***env, int *execve_flag) { char **path; char **cmd_arg; if (ft_strsrch(command, '|') != -1) exec_pipe(env, command, execve_flag); else { cmd_arg = get_clean_arg(command, *env); if (((path = ft_path(env, cmd_arg[0])) == NULL) && ft_strcmp(command, "exit") != 0) ft_putendl("Set a good path or you will take expensive."); if ((ft_rd(command, env, execve_flag) == 1) && (builtin(env, cmd_arg) == 0)) { ft_execute_cmd(path, cmd_arg, *env, execve_flag); if (path) ft_tabfree(path); } } }
static lval * lval_eval_sexpr(lval *v) { /* Evaluate children */ for (int i = 0; i < v->count; i++) { v->cell[i] = lval_eval(v->cell[i]); } /* Error checking */ for (int i = 0; i < v->count; i++) { if (v->cell[i]->type == LVAL_ERR) { return lval_take(v, i); } } /* Empty expression */ if (v->count == 0) { return v; } /* Single expression */ if (v->count == 1) { return lval_take(v, 0); } /* Ensure fist element is symbol */ lval *f = lval_pop(v, 0); if (f->type != LVAL_SYM) { lval_del(f); lval_del(v); return lval_err("S-Expression does not start with symbol!"); } /* Call builtin with operator */ lval *result = builtin(v, f->sym); lval_del(f); return result; }
int main(int argc, char *argv[]) { int i; int argi; Source *s; struct block *l; int restricted, errexit; char **wp; struct env env; pid_t ppid; /* make sure argv[] is sane */ if (!*argv) { static const char *empty_argv[] = { "ksh", (char *) 0 }; argv = (char **) empty_argv; argc = 1; } kshname = *argv; ainit(&aperm); /* initialize permanent Area */ /* set up base environment */ memset(&env, 0, sizeof(env)); env.type = E_NONE; ainit(&env.area); e = &env; newblock(); /* set up global l->vars and l->funs */ /* Do this first so output routines (eg, errorf, shellf) can work */ initio(); initvar(); initctypes(); inittraps(); coproc_init(); /* set up variable and command dictionaries */ ktinit(&taliases, APERM, 0); ktinit(&aliases, APERM, 0); ktinit(&homedirs, APERM, 0); /* define shell keywords */ initkeywords(); /* define built-in commands */ ktinit(&builtins, APERM, 64); /* must be 2^n (currently 40 builtins) */ for (i = 0; shbuiltins[i].name != NULL; i++) builtin(shbuiltins[i].name, shbuiltins[i].func); for (i = 0; kshbuiltins[i].name != NULL; i++) builtin(kshbuiltins[i].name, kshbuiltins[i].func); init_histvec(); def_path = _PATH_DEFPATH; { size_t len = confstr(_CS_PATH, (char *) 0, 0); char *new; if (len > 0) { confstr(_CS_PATH, new = alloc(len + 1, APERM), len + 1); def_path = new; } }
int main(int argc, char **argv) { for (;;) { int c = getopt(argc, argv, "y"); if (c == -1) break; switch (c) { case 'y': option_easy = 1; option_prompt = "> "; break; default: fprintf(stderr, "unrecognized option: %c\n", c); break; } } field_init_z(Z); field_init_multiz(M); symtab_init(tab); builtin(fun_rnd); builtin(fun_random); builtin(fun_ord); builtin(fun_order); builtin(fun_nextprime); builtin(fun_sqrt); builtin(fun_inv); builtin(fun_type); builtin(fun_pairing); builtin(fun_zmod); builtin(fun_poly); builtin(fun_polymod); builtin(fun_extend); builtin(fun_exit); builtin(fun_CHECK); builtin(fun_init_pairing_a); builtin(fun_init_pairing_d); builtin(fun_init_pairing_e); builtin(fun_init_pairing_f); builtin(fun_init_pairing_g); builtin(fun_init_pairing_i); run_init_pairing_a(NULL); symtab_put(reserved, val_new_field(M), "M"); symtab_put(reserved, val_new_field(Z), "Z"); if (argc > optind) { FILE *fp = fopen(argv[optind], "r"); if (!fp) pbc_die("fopen failed on %s", argv[optind]); YY_BUFFER_STATE st = yy_create_buffer(fp, YY_BUF_SIZE); yy_switch_to_buffer(st); yywrapfun = yywrap_return1; yyparse(); yy_delete_buffer(st); } else { yywrapfun = yywrap_readline; yywrap(); while (!end_of_input) { if (2 == yyparse()) pbc_die("parser out of memory"); } putchar('\n'); } symtab_clear(tab); field_clear(M); return 0; }
intrcall(Namep np, struct Listblock *argsp, int nargs) #endif { int i, rettype; Addrp ap; register struct Specblock *sp; register struct Chain *cp; expptr q, ep; int mtype; int op; int f1field, f2field, f3field; packed.ijunk = np->vardesc.varno; f1field = packed.bits.f1; f2field = packed.bits.f2; f3field = packed.bits.f3; if(nargs == 0) goto badnargs; mtype = 0; for(cp = argsp->listp ; cp ; cp = cp->nextp) { ep = (expptr)cp->datap; if( ISCONST(ep) && ep->headblock.vtype==TYSHORT ) cp->datap = (char *) mkconv(tyint, ep); mtype = maxtype(mtype, ep->headblock.vtype); } switch(f1field) { case INTRBOOL: op = f3field; if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) ) goto badtype; if(op == OPBITNOT) { if(nargs != 1) goto badnargs; q = mkexpr(OPBITNOT, (expptr)argsp->listp->datap, ENULL); } else { if(nargs != 2) goto badnargs; q = mkexpr(op, (expptr)argsp->listp->datap, (expptr)argsp->listp->nextp->datap); } frchain( &(argsp->listp) ); free( (charptr) argsp); return(q); case INTRCONV: rettype = f2field; switch(rettype) { case TYLONG: rettype = tyint; break; case TYLOGICAL: rettype = tylog; } if( ISCOMPLEX(rettype) && nargs==2) { expptr qr, qi; qr = (expptr) argsp->listp->datap; qi = (expptr) argsp->listp->nextp->datap; if(ISCONST(qr) && ISCONST(qi)) q = mkcxcon(qr,qi); else q = mkexpr(OPCONV,mkconv(rettype-2,qr), mkconv(rettype-2,qi)); } else if(nargs == 1) { if (f3field && ((Exprp)argsp->listp->datap)->vtype == TYDCOMPLEX) rettype = TYDREAL; q = mkconv(rettype+100, (expptr)argsp->listp->datap); if (q->tag == TADDR) q->addrblock.parenused = 1; } else goto badnargs; q->headblock.vtype = rettype; frchain(&(argsp->listp)); free( (charptr) argsp); return(q); #if 0 case INTRCNST: /* Machine-dependent f77 stuff that f2c omits: intcon contains radix for short int radix for long int radix for single precision radix for double precision precision for short int precision for long int precision for single precision precision for double precision emin for single precision emin for double precision emax for single precision emax for double prcision largest short int largest long int realcon contains tiny for single precision tiny for double precision huge for single precision huge for double precision mrsp (epsilon) for single precision mrsp (epsilon) for double precision */ { register struct Incstblock *cstp; extern ftnint intcon[14]; extern double realcon[6]; cstp = consttab + f3field; for(i=0 ; i<f2field ; ++i) if(cstp->atype == mtype) goto foundconst; else ++cstp; goto badtype; foundconst: switch(cstp->rtype) { case TYLONG: return(mkintcon(intcon[cstp->constno])); case TYREAL: case TYDREAL: return(mkrealcon(cstp->rtype, realcon[cstp->constno]) ); default: Fatal("impossible intrinsic constant"); } } #endif case INTRGEN: sp = spectab + f3field; if(no66flag) if(sp->atype == mtype) goto specfunct; else err66("generic function"); for(i=0; i<f2field ; ++i) if(sp->atype == mtype) goto specfunct; else ++sp; warn1 ("bad argument type to intrinsic %s", np->fvarname); /* Made this a warning rather than an error so things like "log (5) ==> log (5.0)" can be accommodated. When none of these cases matches, the argument is cast up to the first type in the spectab list; this first type is assumed to be the "smallest" type, e.g. REAL before DREAL before COMPLEX, before DCOMPLEX */ sp = spectab + f3field; mtype = sp -> atype; goto specfunct; case INTRSPEC: sp = spectab + f3field; specfunct: if(tyint==TYLONG && ONEOF(sp->rtype,M(TYSHORT)|M(TYLOGICAL)) && (sp+1)->atype==sp->atype) ++sp; if(nargs != sp->nargs) goto badnargs; if(mtype != sp->atype) goto badtype; /* NOTE!! I moved fixargs (YES) into the ELSE branch so that constants in the inline expression wouldn't get put into the constant table */ fixargs (NO, argsp); cast_args (mtype, argsp -> listp); if(q = Inline((int)(sp-spectab), mtype, argsp->listp)) { frchain( &(argsp->listp) ); free( (charptr) argsp); } else { if(sp->othername) { /* C library routines that return double... */ /* sp->rtype might be TYREAL */ ap = builtin(sp->rtype, callbyvalue[sp->othername], 1); q = fixexpr((Exprp) mkexpr(OPCCALL, (expptr)ap, (expptr)argsp) ); } else { fixargs(YES, argsp); ap = builtin(sp->rtype, sp->spxname, 0); q = fixexpr((Exprp) mkexpr(OPCALL, (expptr)ap, (expptr)argsp) ); } /* else */ } /* else */ return(q); case INTRMIN: case INTRMAX: if(nargs < 2) goto badnargs; if( ! ONEOF(mtype, MSKINT|MSKREAL) ) goto badtype; argsp->vtype = mtype; q = mkexpr( (f1field==INTRMIN ? OPMIN : OPMAX), (expptr)argsp, ENULL); q->headblock.vtype = mtype; rettype = f2field; if(rettype == TYLONG) rettype = tyint; else if(rettype == TYUNKNOWN) rettype = mtype; return( mkconv(rettype, q) ); default: fatali("intrcall: bad intrgroup %d", f1field); } badnargs: errstr("bad number of arguments to intrinsic %s", np->fvarname); goto bad; badtype: errstr("bad argument type to intrinsic %s", np->fvarname); bad: return( errnode() ); }
/* * eval - Evaluate the command line that the user has just typed in * * If the user has requested a built-in command (quit, jobs, bg or fg) * then execute it immediately. Otherwise, fork a child process and * run the job in the context of the child. If the job is running in * the foreground, wait for it to terminate and then return. Note: * each child process must have a unique process group ID so that our * background children don't receive SIGINT (SIGTSTP) from the kernel * when we type ctrl-c (ctrl-z) at the keyboard. */ void eval(char *cmdline) { int bg; /* should the job run in bg or fg? */ struct cmdline_tokens tok; pid_t pid; /* recorrd the process id of child process*/ int jid; /* record job id*/ sigset_t mask,emptyset; /* mask is a set of signal to be handled, emptyset is for sigsuspend */ sigemptyset(&emptyset); /* Parse command line */ bg = parseline(cmdline, &tok); if (bg == -1) /* parsing error */ return; if (tok.argv[0] == NULL) /* ignore empty lines */ return; if(!builtin(&tok)) { /* *before starting the process of a child, signals shall *be blocked in case of race problem */ sigemptyset(&mask); sigaddset(&mask,SIGCHLD); sigaddset(&mask,SIGINT); sigaddset(&mask,SIGTSTP); sigprocmask(SIG_BLOCK,&mask,NULL); /* * child process */ if((pid=fork())==0) { /* child process inherit from the parent process, so the blocked signals should be restored here.*/ sigprocmask(SIG_UNBLOCK,&mask,NULL); //each child process should be in a different group setpgid(0,0); // children process enable redirection redirect(tok.infile,tok.outfile); //children process loads a program and never return unless error if(execve(tok.argv[0],tok.argv,environ)<0) { printf("%s: Command not found!\n",tok.argv[0]); exit(0); } } /* *parent process */ if(bg) { addjob(job_list,pid,BG,cmdline); // parent reenable the signal interuption sigprocmask(SIG_UNBLOCK,&mask,NULL); jid=pid2jid(pid); printf("[%d] (%d) %s\n",jid,pid,cmdline); } if(!bg) { addjob(job_list,pid,FG,cmdline); sigprocmask(SIG_UNBLOCK,&mask,NULL); /* * as a foreground job, parent process will wait *for the child to cease. */ while(fgpid(job_list)) { sigsuspend(&emptyset); } } } return; }
int eval_line(char *cmdline, int e_flag) { char *_argv[MAXARGS]; /* _argv for execve(), denoted by underscore to distinguish from main argv array*/ char buf[MAXLINE]; /* holds modified command line */ int background; /* should the job run in background or foreground? */ pid_t pid; /* process id */ int ret = EXIT_SUCCESS; strcpy(buf, cmdline); /* buf[] will be modified by parse() */ /* build the argv array */ background = parse(buf, _argv); if(e_flag > 0) Echo(_argv); if (_argv[0] == NULL) /* ignore empty lines */ { return ret; } if (builtin(_argv, process_table) == 1) /* the work is done */ { return ret; } if(background) { block_signal(SIGINT, 1); } /* child runs user job */ if ((pid = fork()) == 0) { if (execvp(_argv[0], _argv/*, environ*/) == -1) { printf("%s: execve failed: %s\n", _argv[0], strerror(errno)); _exit(EXIT_FAILURE); } } if (background && pid != 0) /* parent waits for foreground job to terminate */ { printf("background process %d: %s", (int) pid, cmdline); // Add to process table: int err; if( (err = insert_process_table(process_table, pid)) == -1) { fprintf(stderr, "insert_process_table failed: line %d: %s\n", __LINE__, strerror(errno)); } // Passing 0 unblocks the signal. block_signal(SIGINT, 0); } else { if (waitpid(pid, &ret, 0) == -1) { printf("%s: waitpid failed: %s\n", _argv[0], strerror(errno)); exit(EXIT_FAILURE); } // If in verbose mode, print out a detailed message: if(verbose) { printf("process %d, completed normally, status %d\n", pid, ret); } } return ret; }
void visit(const Structure* structure) { Assert(isTheoryOpen()); printTab(); output() << "Data: " << '\n'; indent(); auto voc = structure->vocabulary(); for (auto it = voc->firstSort(); it != voc->lastSort(); ++it) { auto s = it->second; if (not s->builtin()) { printTab(); auto name = s->name(); name = capitalize(name); output() << name << " = "; auto st = structure->inter(s); visit(st); output() << '\n'; } } for (auto it = voc->firstPred(); it != voc->lastPred(); ++it) { auto sp = it->second->nonbuiltins(); for (auto jt = sp.cbegin(); jt != sp.cend(); ++jt) { auto p = *jt; if (p->arity() == 1 && p->sorts()[0]->pred() == p) { // If it is in fact a sort, ignore it continue; } auto pi = structure->inter(p); if (pi->ct()->size() == 0 && pi->cf()->size() == 0) { continue; } if (not pi->approxTwoValued()) { output() << "Partial: " << '\n'; //TEMPORARY GO TO PARTIAL BLOCK } printTab(); auto name = p->nameNoArity(); name = capitalize(name); output() << name << " = "; visit(pi->ct()); if (not pi->approxTwoValued()) { visit(pi->cf()); output() << '\n'; output() << "Data: "; //RETURN TO DATA BLOCK } output() << '\n'; } } for (auto it = voc->firstFunc(); it != voc->lastFunc(); ++it) { auto sf = it->second->nonbuiltins(); for (auto jt = sf.cbegin(); jt != sf.cend(); ++jt) { auto f = *jt; auto fi = structure->inter(f); if (fi->approxTwoValued()) { printTab(); auto name = f->nameNoArity(); name = capitalize(name); output() << name << " = "; auto ft = fi->funcTable(); visit(ft); } else { auto pi = fi->graphInter(); auto ct = pi->ct(); auto cf = pi->cf(); if (ct->approxEmpty() && cf->approxEmpty()) { continue; } output() << "Partial: " << '\n'; //TEMPORARY GO TO PARTIAL BLOCK printTab(); auto name = f->nameNoArity(); name = capitalize(name); output() << name << " = "; printAsFunc(ct); printAsFunc(cf); output() << '\n'; output() << "Data: "; //RETURN TO DATA BLOCK } output() << '\n'; } } unindent(); output() << '\n'; }
// si le premier parametre est une commande integree, // l'executer et renvoyer "vrai" bool builtin_command(char **argv) { if (argv[0] == NULL) // commande vide return true; if (strcmp(argv[0], "&") == 0) // ignorer & tout seul return true; builtin("exit", exit_try()); builtin("quit", exit_try()); builtin("jobs", builtin_jobs()); builtin("fg", builtin_fg(argv)); builtin("bg", builtin_bg(argv)); builtin("int", builtin_int(argv)); builtin("term", builtin_term(argv)); builtin("stop", builtin_stop(argv)); builtin("wait", builtin_wait()); builtin("dirs", dirs_print()); builtin("cd", dirs_cd(argv[1])); builtin("pushd", dirs_pushd(argv[1])); builtin("popd", dirs_popd()); return false; // ce n'est pas une commande integree }
int execute(TREPTR argt, int execflg, int *pf1, int *pf2) { /* `stakbot' is preserved by this routine */ register TREPTR t; STKPTR sav = savstak(); sigchk(); if ((t = argt) && execbrk == 0) { register int treeflgs; int oldexit, type; register char **com; treeflgs = t->tretyp; type = treeflgs & COMMSK; oldexit = exitval; exitval = 0; switch (type) { case TCOM: { STRING a1; int argn, internal; ARGPTR schain = gchain; IOPTR io = t->treio; gchain = 0; argn = getarg((void *)t);/*FIXME*/ com = scan(argn); a1 = com[1]; gchain = schain; if ((internal = syslook(com[0], commands)) || argn == 0) setlist(((COMPTR) t)->comset, 0); if (argn && (flags & noexec) == 0) { /* print command if execpr */ if (flags & execpr) { argn = 0; prs(execpmsg); while (com[argn] != ENDARGS) { prs(com[argn++]); blank(); } newline(); } switch (internal) { case SYSDOT: if (a1) { register int f; if ((f = pathopen(getpath(a1), a1)) < 0) failed(a1, notfound); else execexp(0, f); } break; case SYSTIMES: { struct tms t; times(&t); prt(t.tms_cutime); blank(); prt(t.tms_cstime); newline(); } break; case SYSEXIT: exitsh(a1 ? stoi(a1) : oldexit); case SYSNULL: io = 0; break; case SYSCONT: execbrk = -loopcnt; break; case SYSBREAK: if ((execbrk = loopcnt) && a1) breakcnt = stoi(a1); break; case SYSTRAP: if (a1) { BOOL clear; if ((clear = digit(*a1)) == 0) ++com; while (*++com) { int i; if ((i = stoi(*com)) >= MAXTRAP || i < MINTRAP) failed(*com, badtrap); else if (clear) clrsig(i); else { replace(&trapcom[i], a1); if (*a1) getsig(i); else ignsig(i); } } } else { /* print out current traps */ int i; for (i = 0; i < MAXTRAP; i++) { if (trapcom[i]) { prn(i); prs(colon); prs(trapcom[i]); newline(); } } } break; case SYSEXEC: com++; initio(io); ioset = 0; io = 0; if (a1 == 0) break; case SYSLOGIN: flags |= forked; oldsigs(); execa((const char **)com); done(); case SYSCD: if (flags & rshflg) failed(com[0], restricted); else if ((a1 == 0 && (a1 = (char *)homenod.namval) == 0) || chdir(a1) < 0) /* FIXME */ failed(a1, baddir); break; case SYSSHFT: if (dolc < 1) error(badshift); else { dolv++; dolc--; } assnum(&dolladr, dolc); break; case SYSWAIT: await(-1); break; case SYSREAD: exitval = readvar(&com[1]); break; /* case SYSTST: exitval=testcmd(com); break; */ case SYSSET: if (a1) { int argc; argc = options(argn, (const char **)com); if (argc > 1) setargs((const char **)com + argn - argc); } else if (((COMPTR) t)->comset == 0) /* Scan name chain and print */ namscan(printnam); break; case SYSRDONLY: exitval = N_RDONLY; case SYSXPORT: if (exitval == 0) exitval = N_EXPORT;; if (a1) { while (*++com) attrib(lookup(*com), exitval); } else { namscan(printflg); } exitval = 0; break; case SYSEVAL: if (a1) execexp(a1, (UFD)&com[2]); /* FIXME */ break; case SYSUMASK: if (a1) { int c, i; i = 0; while ((c = *a1++) >= '0' && c <= '7') i = (i << 3) + c - '0'; umask(i); } else { int i, j; umask(i = umask(0)); prc('0'); for (j = 6; j >= 0; j -= 3) prc(((i >> j) & 07) + '0'); newline(); } break; default: internal = builtin(argn, com); } if (internal) { if (io) error(illegal); chktrap(); break; } } else if (t->treio == 0) break; } case TFORK: if (execflg && (treeflgs & (FAMP | FPOU)) == 0) parent = 0; else { while ((parent = fork()) == -1) { sigchk(); alarm(10); pause(); } } if (parent) { /* This is the parent branch of fork; */ /* it may or may not wait for the child. */ if (treeflgs & FPRS && flags & ttyflg) { prn(parent); newline(); } if (treeflgs & FPCL) closepipe(pf1); if ((treeflgs & (FAMP | FPOU)) == 0) await(parent); else if ((treeflgs & FAMP) == 0) post(parent); else assnum(&pcsadr, parent); chktrap(); break; } else { /* this is the forked branch (child) of execute */ flags |= forked; iotemp = 0; postclr(); settmp(); /* Turn off INTR and QUIT if `FINT' */ /* Reset ramaining signals to parent */ /* except for those `lost' by trap */ oldsigs(); if (treeflgs & FINT) { signal(INTR, SIG_IGN); signal(QUIT, SIG_IGN); } /* pipe in or out */ if (treeflgs & FPIN) { sh_rename(pf1[INPIPE], 0); close(pf1[OTPIPE]); } if (treeflgs & FPOU) { sh_rename(pf2[OTPIPE], 1); close(pf2[INPIPE]); } /* default std input for & */ if (treeflgs & FINT && ioset == 0) sh_rename(chkopen(devnull), 0); /* io redirection */ initio(t->treio); if (type != TCOM) execute(((FORKPTR) t)->forktre, 1, NULL, NULL); else if (com[0] != ENDARGS) { setlist(((COMPTR) t)->comset, N_EXPORT); execa((const char **)com); } done(); } case TPAR: sh_rename(dup(2), output); execute(((PARPTR) t)->partre, execflg, NULL, NULL); done(); case TFIL: { int pv[2]; chkpipe(pv); if (execute(((LSTPTR) t)->lstlef, 0, pf1, pv) == 0) execute(((LSTPTR) t)->lstrit, execflg, pv, pf2); else closepipe(pv); break; } case TLST: execute(((LSTPTR) t)->lstlef, 0, NULL, NULL); execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL); break; case TAND: if (execute(((LSTPTR) t)->lstlef, 0, NULL, NULL) == 0) execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL); break; case TORF: if (execute(((LSTPTR) t)->lstlef, 0, NULL, NULL) != 0) execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL); break; case TFOR: { NAMPTR n = lookup(((FORPTR) t)->fornam); char **args; DOLPTR argsav = 0; if (((FORPTR) t)->forlst == 0) { args = (char **)dolv + 1; argsav = useargs(); } else { ARGPTR schain = gchain; gchain = 0; trim((args = scan(getarg(((FORPTR) t)->forlst)))[0]); gchain = schain; } loopcnt++; while (*args != ENDARGS && execbrk == 0) { assign(n, *args++); execute(((FORPTR) t)->fortre, 0, NULL, NULL); if (execbrk < 0) { execbrk = 0; } } if (breakcnt) breakcnt--; execbrk = breakcnt; loopcnt--; argfor = freeargs(argsav); break; } case TWH: case TUN: { int i = 0; loopcnt++; while (execbrk == 0 && (execute(((WHPTR) t)->whtre, 0, NULL, NULL) == 0) == (type == TWH)) { i = execute(((WHPTR) t)->dotre, 0, NULL, NULL); if (execbrk < 0) execbrk = 0; } if (breakcnt) breakcnt--; execbrk = breakcnt; loopcnt--; exitval = i; break; } case TIF: if (execute(((IFPTR) t)->iftre, 0, NULL, NULL) == 0) execute(((IFPTR) t)->thtre, execflg, NULL, NULL); else execute(((IFPTR) t)->eltre, execflg, NULL, NULL); break; case TSW: { register char *r = mactrim(((SWPTR) t)->swarg); t = (TREPTR) ((SWPTR) t)->swlst; while (t) { ARGPTR rex = ((REGPTR) t)->regptr; while (rex) { register char *s; if (gmatch(r, s = macro(rex->argval)) || (trim(s), eq(r, s))) { execute(((REGPTR)t)->regcom, 0, NULL, NULL); t = 0; break; } else rex = ((ARGPTR)rex)->argnxt; } if (t) t = (TREPTR) ((REGPTR) t)->regnxt; } } break; } exitset(); }
void execute(struct treenode *node, int *pipe1, int *pipe2) { int flag, ret; pid_t pid; int pv[2]; struct treenode *tmp; if (node == NULL) { return; } switch (node->type) { case CMDLIST: flag = node->flags; execute(node->left, NULL, NULL); execute(node->right, NULL, NULL); free_treenode(node); return; //why return? Because the rest will be executed by child. case FILTER: flag = node->flags; pipe(pv); tmp = node->left; tmp->flags |= PIPE_OUT | (flag & (PIPE_IN | LAST_IN_PAR)); execute(node->left, pipe1, pv); tmp = node->right; tmp->flags |= PIPE_IN | (flag & (PIPE_OUT | AND | LAST_IN_PAR)); execute(node->right, pv, pipe2); free_treenode(node); return; case COMMAND: if (builtin(node) == 0) { free_treenode(node); return; } case PARENTHESES: pid = 0; flag = node->flags; //if the LAST_IN_PAR, not fork, use the current if ((flag & LAST_IN_PAR) == 0) { pid = fork(); if (pid == -1) { perror("fail to fork"); return; } } // parent if (pid != 0) { if ((flag & PIPE_IN) != 0) { close(pipe1[0]); close(pipe1[1]); } if ((flag & AND) != 0) { printf("%d\n", pid); free_treenode(node); return; } pwait(pid); free_treenode(node); return; } //child if (node->in || node->out) { if (redirect(node) != 0) { exit(-1); } } if ((flag & PIPE_IN) != 0) { close(STDIN_FILENO); dup(pipe1[0]); close(pipe1[0]); close(pipe1[1]); } if ((flag & PIPE_OUT) != 0) { close(STDOUT_FILENO); dup(pipe2[1]); close(pipe2[1]); close(pipe2[0]); } if (node->type == PARENTHESES) { tmp = node->child; execute(tmp, NULL, NULL); exit(1); } ret = execute_cmd(node); exit(ret); } }
/* * Do macro expansion in a row of tokens. * Flag is NULL if more input can be gathered. */ void expandrow(Tokenrow * trp, char *flag) { Token * tp; Nlist * np; MacroValidatorList validators; mvl_init(&validators); /* Sets all token-identifiers to 0 because tokens may not be initialised (never use C!) */ tokenrow_zeroTokenIdentifiers(trp); if (flag) setsource(flag, -1, -1, "", 0); for (tp = trp->tp; tp < trp->lp;) { mvl_check(&validators, tp); if (tp->type != NAME || quicklook(tp->t[0], tp->len > 1 ? tp->t[1] : 0) == 0 || (np = lookup(tp, 0)) == NULL || (np->flag & (ISDEFINED | ISMAC)) == 0 || (np->flag & ISACTIVE) != 0) { tp++; continue; } trp->tp = tp; if (np->val == KDEFINED) { tp->type = DEFINED; if ((tp + 1) < trp->lp && (tp + 1)->type == NAME) (tp + 1)->type = NAME1; else if ((tp + 3) < trp->lp && (tp + 1)->type == LP && (tp + 2)->type == NAME && (tp + 3)->type == RP) (tp + 2)->type = NAME1; else error(ERROR, "Incorrect syntax for `defined'"); tp++; continue; } else if (np->val == KMACHINE) { if (((tp - 1) >= trp->bp) && ((tp - 1)->type == SHARP)) { tp->type = ARCHITECTURE; if ((tp + 1) < trp->lp && (tp + 1)->type == NAME) (tp + 1)->type = NAME2; else if ((tp + 3) < trp->lp && (tp + 1)->type == LP && (tp + 2)->type == NAME && (tp + 3)->type == RP) (tp + 2)->type = NAME2; else error(ERROR, "Incorrect syntax for `#machine'"); } tp++; continue; } if (np->flag & ISMAC) builtin(trp, np->val); else expand(trp, np, &validators); tp = trp->tp; } // end for if (flag) unsetsource(); mvl_destruct(&validators); }
/* main - Start of shell, doesn't care for arguments */ int main(int argc, char* argv[]) { int retval; char cmd_line[MAX_LENGTH]; /* Allocate memory for argument vector */ char **args = (char **) malloc(MAX_ARGS * sizeof(char*)); /* Register proper signals to handle */ register_signals(); /* Set string for promt */ USER = getenv("USER"); /* Main loop */ while (1) { #ifndef SIGNALDETECTION /* Check if any background processes has exited */ retval = check_background_procs(); if (retval == -1 && errno != ECHILD) perror("wait failed"); #endif /* Print a new promt */ print_prompt(); /* Fetch new command from terminal */ if (fgets(cmd_line, MAX_LENGTH, stdin) != NULL) /* Success */ { /* Parse user command */ retval = parse_command(cmd_line, args); if (retval == 1) /* Empty cmd */ continue; /* Restart loop, for checking background etc.. */ /* If the command is available as a builtin, use that */ if (builtin(args)) { retval = run_builtin(args); if (retval == B_EXIT) /* EXIT */ { retval = check_background_procs(); /* retval == 0 means no error for having no children were * returned */ /* Kill all child processes */ if (retval == 0) retval = kill(-getpid(), SIGKILL); break; /* Breaks main loop and exits */ } else if (retval == B_FALIURE) /* Something went wrong */ fprintf(stderr, "Command, %s, could not be executed\n", args[0]); } else /* Run a command */ { /* Run in the background */ if (background(args)) { run_program(args, 1); } else /* Run blocking */ { retval = run_program_block(args); if (retval IS_ERROR) { if (retval == INVALIDARGS) fprintf(stderr, "Invalid argument\n"); else if (retval == PIPEERROR) fprintf(stderr, "Pipe error\n"); else if (retval == FORKERROR) fprintf(stderr, "Fork error\n"); } } } } } /* Free memmory */ free(args); return 0; }
int main(int argc, char **argv) { int ierr, nhits, vselect; const char *conffile; const char *logfile; FILE* output; FastBitQueryHandle qh; FastBitResultSetHandle rh; ierr = 0; vselect = 1; logfile = 0; conffile = 0; #if defined(DEBUG) || defined(_DEBUG) #if DEBUG + 0 > 10 || _DEBUG + 0 > 10 ierr = INT_MAX; #elif DEBUG + 0 > 0 ierr += 7 * DEBUG; #elif _DEBUG + 0 > 0 ierr += 5 * _DEBUG; #else ierr += 3; #endif #endif /* process arguments started with - */ while (vselect < argc && argv[vselect][0] == '-') { if (argv[vselect][1] == 'c' || argv[vselect][1] == 'C') { if (vselect+1 < argc) { conffile = argv[vselect+1]; vselect += 2; } else { vselect += 1; } } else if (argv[vselect][1] == 'h' || argv[vselect][1] == 'H') { usage(*argv); vselect += 1; } #if defined(TCAPI_USE_LOGFILE) else if (argv[vselect][1] == 'l' || argv[vselect][1] == 'L') { if (vselect+1 < argc) { logfile = argv[vselect+1]; vselect += 2; } else { vselect += 1; } } #endif else if (argv[vselect][1] == 'm' || argv[vselect][1] == 'M' || argv[vselect][1] == 'v' || argv[vselect][1] == 'V') { if (vselect+1 < argc && (isdigit(argv[vselect+1][0]) != 0 || (argv[vselect+1][0] == '-' && isdigit(argv[vselect+1][1]) != 0))) { ierr += atoi(argv[vselect+1]); vselect += 2; } else { ierr += 1; vselect += 1; } } else { fprintf(stderr, "%s: unknown option %s\n", *argv, argv[vselect]); ++ vselect; } } fastbit_init((const char*)conffile); fastbit_set_verbose_level(ierr); fastbit_set_logfile(logfile); #if defined(TCAPI_USE_LOGFILE) output = fastbit_get_logfilepointer(); printf("%s: output=0x%8.8x, stdout=0x%8.8x\n", *argv, output, stdout); #else output = stdout; #endif if (argc <= vselect) { builtin(*argv, output); return -1; } if (argc == vselect+1) /* buld indexes */ return fastbit_build_indexes(argv[vselect], (const char*)0); qh = fastbit_build_query(0, argv[vselect], argv[vselect+1]); if (qh == 0) { fprintf(output, "%s failed to process query \"%s\" on data in %s\n", argv[0], argv[vselect+1], argv[vselect]); fastbit_cleanup(); return -2; } nhits = fastbit_get_result_rows(qh); fprintf(output, "%s: applying \"%s\" on data in %s produced %d hit%s\n", argv[0], argv[vselect+1], argv[vselect], nhits, (nhits>1 ? "s" : "")); if (nhits <= 0) return 0; /* print the selected values specified in the select clause. Since the select clause was nil in the call to fastbit_build_query, there would be nothing to print here! */ rh = fastbit_build_result_set(qh); if (rh != 0) { int ncols = fastbit_get_result_columns(qh); fprintf(output, "%s\n", fastbit_get_select_clause(qh)); while (fastbit_result_set_next(rh) == 0) { int i; fprintf(output, "%s", fastbit_result_set_getString(rh, 0)); for (i = 1; i < ncols; ++ i) fprintf(output, ", %s", fastbit_result_set_getString(rh, i)); fprintf(output, "\n"); } fastbit_destroy_result_set(rh); } fflush(output); vselect += 2; /* print attributes explicitly specified on the command line */ if (argc > vselect) { int i, j; for (i = vselect; i < argc; i += 2) { char t = (i+1<argc ? argv[i+1][0] : 'i'); switch (t) { default: case 'i': case 'I': { const int32_t *tmp = fastbit_get_qualified_ints(qh, argv[i]); if (tmp != 0) { fprintf(output, "%s[%d]=", argv[i], nhits); for (j = 0; j < nhits; ++ j) fprintf(output, "%d ", (int)tmp[j]); fprintf(output, "\n"); } else { fprintf(output, "%s: failed to retrieve values for " "column %s (requested type %c)\n", argv[0], argv[i], t); } break;} case 'u': case 'U': { const uint32_t *tmp = fastbit_get_qualified_uints(qh, argv[i]); if (tmp != 0) { fprintf(output, "%s[%d]=", argv[i], nhits); for (j = 0; j < nhits; ++ j) fprintf(output, "%u ", (unsigned)tmp[j]); fprintf(output, "\n"); } else { fprintf(output, "%s: failed to retrieve value for " "column %s (requested type %c)\n", argv[0], argv[i], t); } break;} case 'l': case 'L': { const int64_t *tmp = fastbit_get_qualified_longs(qh, argv[i]); if (tmp != 0) { fprintf(output, "%s[%d]=", argv[i], nhits); for (j = 0; j < nhits; ++ j) fprintf(output, "%lld ", (long long)tmp[j]); fprintf(output, "\n"); } else { fprintf(output, "%s: failed to retrieve value for " "column %s (requested type %c)\n", argv[0], argv[i], t); } break;} case 'r': case 'R': case 'f': case 'F': { const float *tmp = fastbit_get_qualified_floats(qh, argv[i]); if (tmp != 0) { fprintf(output, "%s[%d]=", argv[i], nhits); for (j = 0; j < nhits; ++ j) fprintf(output, "%g ", tmp[j]); fprintf(output, "\n"); } else { fprintf(output, "%s: failed to retrieve value for " "column %s (requested type %c)\n", argv[0], argv[i], t); } break;} case 'd': case 'D': { const double *tmp = fastbit_get_qualified_doubles(qh, argv[i]); if (tmp != 0) { fprintf(output, "%s[%d]=", argv[i], nhits); for (j = 0; j < nhits; ++ j) fprintf(output, "%lG ", tmp[j]); fprintf(output, "\n"); } else { fprintf(output, "%s: failed to retrieve value for " "column %s (requested type %c)\n", argv[0], argv[i], t); } break;} case 's': case 'S': case 't': case 'T': { const char **tmp = fastbit_get_qualified_strings(qh, argv[i]); if (tmp != 0) { fprintf(output, "%s[%d]=", argv[i], nhits); for (j = 0; j < nhits; ++ j) fprintf(output, "\"%s\" ", tmp[j]); fprintf(output, "\n"); } else { fprintf(output, "%s: failed to retrieve value for " "column %s (requested type %c)\n", argv[0], argv[i], t); } break;} } } } ierr = fastbit_destroy_query(qh); fastbit_cleanup(); return ierr; } /* main */
PUBLIC WORD parse(INT old_nesting) { int nesting = (int) old_nesting; int quoted; nextsym(); if( symb==s_eof ) return nesting; parse_depth++; if( ( quoted = (symb==s_quote) ) != 0 ) nextsym(); /* trace("Parse %squoted depth %d",quoted?"":"un",parse_depth); */ for(;;) { switch ( (int)symb ) { case s_builtin: if(!quoted) { builtin(); break; } case s_macro: if(!quoted) { eval(); break; } case s_hexvar: case s_var: if(!quoted) { evalvar(); break; } default: case s_token: if( toksize == 1 ) wrch(token[0]); else wrstr(token); break; case s_lbra: if( nesting++ > 0) wrch(c_lbra); break; case s_rbra: if( --nesting > 0 ) wrch(c_rbra); break; case s_eof: return nesting; case s_quote: if( quoted ) wrch(c_quote); pbchar(c_quote); nesting = (int) parse((WORD)nesting); break; case s_concat: if( quoted ) wrch(c_concat); break; } if ( nesting <= old_nesting ) break; nextsym(); } parse_depth--; return nesting; }
static int main_init(int argc, const char *argv[], Source **sp, struct block **lp) { int argi, i; Source *s = NULL; struct block *l; unsigned char restricted_shell, errexit, utf_flag; char *cp; const char *ccp, **wp; struct tbl *vp; struct stat s_stdin; #if !defined(_PATH_DEFPATH) && defined(_CS_PATH) ssize_t k; #endif #if defined(MKSH_EBCDIC) || defined(MKSH_FAUX_EBCDIC) ebcdic_init(); #endif set_ifs(TC_IFSWS); #ifdef __OS2__ os2_init(&argc, &argv); #endif /* do things like getpgrp() et al. */ chvt_reinit(); /* make sure argv[] is sane, for weird OSes */ if (!*argv) { argv = empty_argv; argc = 1; } kshname = argv[0]; /* initialise permanent Area */ ainit(&aperm); /* max. name length: -2147483648 = 11 (+ NUL) */ vtemp = alloc(offsetof(struct tbl, name[0]) + 12, APERM); /* set up base environment */ env.type = E_NONE; ainit(&env.area); /* set up global l->vars and l->funs */ newblock(); /* Do this first so output routines (eg, errorf, shellf) can work */ initio(); /* determine the basename (without '-' or path) of the executable */ ccp = kshname; goto begin_parsing_kshname; while ((i = ccp[argi++])) { if (mksh_cdirsep(i)) { ccp += argi; begin_parsing_kshname: argi = 0; if (*ccp == '-') ++ccp; } } if (!*ccp) ccp = empty_argv[0]; /* * Turn on nohup by default. (AT&T ksh does not have a nohup * option - it always sends the hup). */ Flag(FNOHUP) = 1; /* * Turn on brace expansion by default. AT&T kshs that have * alternation always have it on. */ Flag(FBRACEEXPAND) = 1; /* * Turn on "set -x" inheritance by default. */ Flag(FXTRACEREC) = 1; /* define built-in commands and see if we were called as one */ ktinit(APERM, &builtins, /* currently up to 54 builtins: 75% of 128 = 2^7 */ 7); for (i = 0; mkshbuiltins[i].name != NULL; i++) if (!strcmp(ccp, builtin(mkshbuiltins[i].name, mkshbuiltins[i].func))) Flag(FAS_BUILTIN) = 1; if (!Flag(FAS_BUILTIN)) { /* check for -T option early */ argi = parse_args(argv, OF_FIRSTTIME, NULL); if (argi < 0) return (1); #if defined(MKSH_BINSHPOSIX) || defined(MKSH_BINSHREDUCED) /* are we called as -sh or /bin/sh or so? */ if (!strcmp(ccp, "sh" MKSH_EXE_EXT)) { /* either also turns off braceexpand */ #ifdef MKSH_BINSHPOSIX /* enable better POSIX conformance */ change_flag(FPOSIX, OF_FIRSTTIME, true); #endif #ifdef MKSH_BINSHREDUCED /* enable kludge/compat mode */ change_flag(FSH, OF_FIRSTTIME, true); #endif } #endif } initvar(); inittraps(); coproc_init(); /* set up variable and command dictionaries */ ktinit(APERM, &taliases, 0); ktinit(APERM, &aliases, 0); #ifndef MKSH_NOPWNAM ktinit(APERM, &homedirs, 0); #endif /* define shell keywords */ initkeywords(); init_histvec(); /* initialise tty size before importing environment */ change_winsz(); #ifdef _PATH_DEFPATH def_path = _PATH_DEFPATH; #else #ifdef _CS_PATH if ((k = confstr(_CS_PATH, NULL, 0)) > 0 && confstr(_CS_PATH, cp = alloc(k + 1, APERM), k + 1) == k + 1) def_path = cp; else #endif /* * this is uniform across all OSes unless it * breaks somewhere hard; don't try to optimise, * e.g. add stuff for Interix or remove /usr * for HURD, because e.g. Debian GNU/HURD is * "keeping a regular /usr"; this is supposed * to be a sane 'basic' default PATH */ def_path = MKSH_UNIXROOT "/bin" MKSH_PATHSEPS MKSH_UNIXROOT "/usr/bin" MKSH_PATHSEPS MKSH_UNIXROOT "/sbin" MKSH_PATHSEPS MKSH_UNIXROOT "/usr/sbin"; #endif /* * Set PATH to def_path (will set the path global variable). * (import of environment below will probably change this setting). */ vp = global(TPATH); /* setstr can't fail here */ setstr(vp, def_path, KSH_RETURN_ERROR); #ifndef MKSH_NO_CMDLINE_EDITING /* * Set edit mode to emacs by default, may be overridden * by the environment or the user. Also, we want tab completion * on in vi by default. */ change_flag(FEMACS, OF_SPECIAL, true); #if !MKSH_S_NOVI Flag(FVITABCOMPLETE) = 1; #endif #endif /* import environment */ init_environ(); /* override default PATH regardless of environment */ #ifdef MKSH_DEFPATH_OVERRIDE vp = global(TPATH); setstr(vp, MKSH_DEFPATH_OVERRIDE, KSH_RETURN_ERROR); #endif /* for security */ typeset(TinitIFS, 0, 0, 0, 0); /* assign default shell variable values */ typeset("PATHSEP=" MKSH_PATHSEPS, 0, 0, 0, 0); substitute(initsubs, 0); /* Figure out the current working directory and set $PWD */ vp = global(TPWD); cp = str_val(vp); /* Try to use existing $PWD if it is valid */ set_current_wd((mksh_abspath(cp) && test_eval(NULL, TO_FILEQ, cp, Tdot, true)) ? cp : NULL); if (current_wd[0]) simplify_path(current_wd); /* Only set pwd if we know where we are or if it had a bogus value */ if (current_wd[0] || *cp) /* setstr can't fail here */ setstr(vp, current_wd, KSH_RETURN_ERROR); for (wp = initcoms; *wp != NULL; wp++) { c_builtin(wp); while (*wp != NULL) wp++; } setint_n(global("OPTIND"), 1, 10); kshuid = getuid(); kshgid = getgid(); kshegid = getegid(); safe_prompt = ksheuid ? "$ " : "# "; vp = global("PS1"); /* Set PS1 if unset or we are root and prompt doesn't contain a # */ if (!(vp->flag & ISSET) || (!ksheuid && !strchr(str_val(vp), '#'))) /* setstr can't fail here */ setstr(vp, safe_prompt, KSH_RETURN_ERROR); setint_n((vp = global("BASHPID")), 0, 10); vp->flag |= INT_U; setint_n((vp = global("PGRP")), (mksh_uari_t)kshpgrp, 10); vp->flag |= INT_U; setint_n((vp = global("PPID")), (mksh_uari_t)kshppid, 10); vp->flag |= INT_U; setint_n((vp = global("USER_ID")), (mksh_uari_t)ksheuid, 10); vp->flag |= INT_U; setint_n((vp = global("KSHUID")), (mksh_uari_t)kshuid, 10); vp->flag |= INT_U; setint_n((vp = global("KSHEGID")), (mksh_uari_t)kshegid, 10); vp->flag |= INT_U; setint_n((vp = global("KSHGID")), (mksh_uari_t)kshgid, 10); vp->flag |= INT_U; setint_n((vp = global("RANDOM")), rndsetup(), 10); vp->flag |= INT_U; setint_n((vp_pipest = global("PIPESTATUS")), 0, 10); /* Set this before parsing arguments */ Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0; /* this to note if monitor is set on command line (see below) */ #ifndef MKSH_UNEMPLOYED Flag(FMONITOR) = 127; #endif /* this to note if utf-8 mode is set on command line (see below) */ UTFMODE = 2; if (!Flag(FAS_BUILTIN)) { argi = parse_args(argv, OF_CMDLINE, NULL); if (argi < 0) return (1); } /* process this later only, default to off (hysterical raisins) */ utf_flag = UTFMODE; UTFMODE = 0; if (Flag(FAS_BUILTIN)) { /* auto-detect from environment variables, always */ utf_flag = 3; } else if (Flag(FCOMMAND)) { s = pushs(SSTRINGCMDLINE, ATEMP); if (!(s->start = s->str = argv[argi++])) errorf(Tf_optfoo, "", "", 'c', Treq_arg); while (*s->str) { if (ctype(*s->str, C_QUOTE)) break; s->str++; } if (!*s->str) s->flags |= SF_MAYEXEC; s->str = s->start; #ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT /* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */ if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--")) ++argi; #endif if (argv[argi]) kshname = argv[argi++]; } else if (argi < argc && !Flag(FSTDIN)) { s = pushs(SFILE, ATEMP); #ifdef __OS2__ /* * A bug in OS/2 extproc (like shebang) handling makes * it not pass the full pathname of a script, so we need * to search for it. This changes the behaviour of a * simple "mksh foo", but can't be helped. */ s->file = argv[argi++]; if (search_access(s->file, X_OK) != 0) s->file = search_path(s->file, path, X_OK, NULL); if (!s->file || !*s->file) s->file = argv[argi - 1]; #else s->file = argv[argi++]; #endif s->u.shf = shf_open(s->file, O_RDONLY, 0, SHF_MAPHI | SHF_CLEXEC); if (s->u.shf == NULL) { shl_stdout_ok = false; warningf(true, Tf_sD_s, s->file, cstrerror(errno)); /* mandated by SUSv4 */ exstat = 127; unwind(LERROR); } kshname = s->file; } else { Flag(FSTDIN) = 1; s = pushs(SSTDIN, ATEMP); s->file = "<stdin>"; s->u.shf = shf_fdopen(0, SHF_RD | can_seek(0), NULL); if (isatty(0) && isatty(2)) { Flag(FTALKING) = Flag(FTALKING_I) = 1; /* The following only if isatty(0) */ s->flags |= SF_TTY; s->u.shf->flags |= SHF_INTERRUPT; s->file = NULL; } } /* this bizarreness is mandated by POSIX */ if (fstat(0, &s_stdin) >= 0 && S_ISCHR(s_stdin.st_mode) && Flag(FTALKING)) reset_nonblock(0); /* initialise job control */ j_init(); /* do this after j_init() which calls tty_init_state() */ if (Flag(FTALKING)) { if (utf_flag == 2) { #ifndef MKSH_ASSUME_UTF8 /* auto-detect from locale or environment */ utf_flag = 4; #else /* this may not be an #elif */ #if MKSH_ASSUME_UTF8 utf_flag = 1; #else /* always disable UTF-8 (for interactive) */ utf_flag = 0; #endif #endif } #ifndef MKSH_NO_CMDLINE_EDITING x_init(); #endif } #ifdef SIGWINCH sigtraps[SIGWINCH].flags |= TF_SHELL_USES; setsig(&sigtraps[SIGWINCH], x_sigwinch, SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP); #endif l = e->loc; if (Flag(FAS_BUILTIN)) { l->argc = argc; l->argv = argv; l->argv[0] = ccp; } else { l->argc = argc - argi; /* * allocate a new array because otherwise, when we modify * it in-place, ps(1) output changes; the meaning of argc * here is slightly different as it excludes kshname, and * we add a trailing NULL sentinel as well */ l->argv = alloc2(l->argc + 2, sizeof(void *), APERM); l->argv[0] = kshname; memcpy(&l->argv[1], &argv[argi], l->argc * sizeof(void *)); l->argv[l->argc + 1] = NULL; getopts_reset(1); } /* divine the initial state of the utf8-mode Flag */ ccp = null; switch (utf_flag) { /* auto-detect from locale or environment */ case 4: #if HAVE_SETLOCALE_CTYPE ccp = setlocale(LC_CTYPE, ""); #if HAVE_LANGINFO_CODESET if (!isuc(ccp)) ccp = nl_langinfo(CODESET); #endif if (!isuc(ccp)) ccp = null; #endif /* FALLTHROUGH */ /* auto-detect from environment */ case 3: /* these were imported from environ earlier */ if (ccp == null) ccp = str_val(global("LC_ALL")); if (ccp == null) ccp = str_val(global("LC_CTYPE")); if (ccp == null) ccp = str_val(global("LANG")); UTFMODE = isuc(ccp); break; /* not set on command line, not FTALKING */ case 2: /* unknown values */ default: utf_flag = 0; /* FALLTHROUGH */ /* known values */ case 1: case 0: UTFMODE = utf_flag; break; } /* Disable during .profile/ENV reading */ restricted_shell = Flag(FRESTRICTED); Flag(FRESTRICTED) = 0; errexit = Flag(FERREXIT); Flag(FERREXIT) = 0; /* * Do this before profile/$ENV so that if it causes problems in them, * user will know why things broke. */ if (!current_wd[0] && Flag(FTALKING)) warningf(false, "can't determine current directory"); if (Flag(FLOGIN)) include(MKSH_SYSTEM_PROFILE, 0, NULL, true); if (!Flag(FPRIVILEGED)) { if (Flag(FLOGIN)) include(substitute("$HOME/.profile", 0), 0, NULL, true); if (Flag(FTALKING)) { cp = substitute("${ENV:-" MKSHRC_PATH "}", DOTILDE); if (cp[0] != '\0') include(cp, 0, NULL, true); } } else { include(MKSH_SUID_PROFILE, 0, NULL, true); /* turn off -p if not set explicitly */ if (Flag(FPRIVILEGED) != 1) change_flag(FPRIVILEGED, OF_INTERNAL, false); } if (restricted_shell) { c_builtin(restr_com); /* After typeset command... */ Flag(FRESTRICTED) = 1; } Flag(FERREXIT) = errexit; if (Flag(FTALKING) && s) hist_init(s); else /* set after ENV */ Flag(FTRACKALL) = 1; alarm_init(); *sp = s; *lp = l; return (0); }
int main(int argc, char *argv[]) { register int i; int argi; Source *s; struct block *l; int restricted, errexit; char **wp; struct env env; pid_t ppid; #ifdef MEM_DEBUG chmem_set_defaults("ct", 1); /* chmem_push("+c", 1); */ #endif /* MEM_DEBUG */ #ifdef OS2 setmode (0, O_BINARY); setmode (1, O_TEXT); #endif /* make sure argv[] is sane */ if (!*argv) { static const char *empty_argv[] = { "pdksh", (char *) 0 }; argv = (char **)__UNCONST(empty_argv); argc = 1; } kshname = *argv; ainit(&aperm); /* initialize permanent Area */ /* set up base environment */ memset(&env, 0, sizeof(env)); env.type = E_NONE; ainit(&env.area); e = &env; newblock(); /* set up global l->vars and l->funs */ /* Do this first so output routines (eg, errorf, shellf) can work */ initio(); initvar(); initctypes(); inittraps(); #ifdef KSH coproc_init(); #endif /* KSH */ /* set up variable and command dictionaries */ tinit(&taliases, APERM, 0); tinit(&aliases, APERM, 0); tinit(&homedirs, APERM, 0); /* define shell keywords */ initkeywords(); /* define built-in commands */ tinit(&builtins, APERM, 64); /* must be 2^n (currently 40 builtins) */ for (i = 0; shbuiltins[i].name != NULL; i++) builtin(shbuiltins[i].name, shbuiltins[i].func); for (i = 0; kshbuiltins[i].name != NULL; i++) builtin(kshbuiltins[i].name, kshbuiltins[i].func); init_histvec(); def_path = DEFAULT__PATH; #if defined(HAVE_CONFSTR) && defined(_CS_PATH) { size_t len = confstr(_CS_PATH, (char *) 0, 0); char *new; if (len > 0) { confstr(_CS_PATH, new = alloc(len + 1, APERM), len + 1); def_path = new; } }