static int primary(enum token n) { enum token nn; int res; if (n == EOI) return 0; /* missing expression */ if (n == LPAREN) { parenlevel++; if ((nn = t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL)) == RPAREN) { parenlevel--; return 0; /* missing expression */ } res = oexpr(nn); if (t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL) != RPAREN) syntax(NULL, "closing paren expected"); parenlevel--; return res; } if (TOKEN_TYPE(n) == UNOP) { /* unary expression */ if (--nargc == 0) syntax(NULL, "argument expected"); /* impossible */ switch (n) { case STREZ: return strlen(*++t_wp) == 0; case STRNZ: return strlen(*++t_wp) != 0; case FILTT: return isatty(getn(*++t_wp)); default: return filstat(*++t_wp, n); } } nn = t_lex(nargc > 0 ? t_wp[1] : NULL); if (TOKEN_TYPE(nn) == BINOP) return binop(nn); return strlen(*t_wp) > 0; }
int c_exitreturn(char **wp) { int how = LEXIT; int n; char *arg; if (ksh_getopt(wp, &builtin_opt, null) == '?') return 1; arg = wp[builtin_opt.optind]; if (arg) { if (!getn(arg, &n)) { exstat = 1; warningf(true, "%s: bad number", arg); } else exstat = n; } if (wp[0][0] == 'r') { /* return */ struct env *ep; /* need to tell if this is exit or return so trap exit will * work right (POSIX) */ for (ep = e; ep; ep = ep->oenv) if (STOP_RETURN(ep->type)) { how = LRETURN; break; } } if (how == LEXIT && !really_exit && j_stopped_running()) { really_exit = 1; how = LSHELL; } quitenv(NULL); /* get rid of any i/o redirections */ unwind(how); /* NOTREACHED */ return 0; }
static int primary(enum token n) { int res; if (n == EOI) syntax(NULL, "argument expected"); if (n == LPAREN) { res = oexpr(t_lex(*++t_wp)); if (t_lex(*++t_wp) != RPAREN) syntax(NULL, "closing paren expected"); return res; } /* * We need this, if not binary operations with more than 4 * arguments will always fall into unary. */ if(t_lex_type(t_wp[1]) == BINOP) { t_lex(t_wp[1]); if (t_wp_op && t_wp_op->op_type == BINOP) return binop(); } if (t_wp_op && t_wp_op->op_type == UNOP) { /* unary expression */ if (*++t_wp == NULL) syntax(t_wp_op->op_text, "argument expected"); switch (n) { case STREZ: return strlen(*t_wp) == 0; case STRNZ: return strlen(*t_wp) != 0; case FILTT: return isatty(getn(*t_wp)); default: return filstat(*t_wp, n); } } return strlen(*t_wp) > 0; }
bool Matrix::operator ==(const Matrix& b) const { float local_m = getm(); float local_n = getn(); // first compare dimensions if(local_m != b.getm()) return false; if(local_n != b.getn()) return false; // now compare each value. for(unsigned int i=0;i<local_m;++i) { for(unsigned int j=0;j<local_n;j++) { if( (*this)[i][j] != b[i][j]) { return false; } } } return true; }
static int primary(shinstance *psh, enum token n) { enum token nn; int res; if (n == EOI) return 0; /* missing expression */ if (n == LPAREN) { if ((nn = t_lex(psh, *++psh->t_wp)) == RPAREN) return 0; /* missing expression */ res = oexpr(psh, nn); if (t_lex(psh, *++psh->t_wp) != RPAREN) syntax(psh, NULL, "closing paren expected"); return res; } if (psh->t_wp_op && psh->t_wp_op->op_type == UNOP) { /* unary expression */ if (*++psh->t_wp == NULL) syntax(psh, psh->t_wp_op->op_text, "argument expected"); switch (n) { case STREZ: return strlen(*psh->t_wp) == 0; case STRNZ: return strlen(*psh->t_wp) != 0; case FILTT: return shfile_isatty(&psh->fdtab, getn(psh, *psh->t_wp)); default: return filstat(psh, *psh->t_wp, n); } } if (t_lex(psh, psh->t_wp[1]), psh->t_wp_op && psh->t_wp_op->op_type == BINOP) { return binop(psh); } return strlen(*psh->t_wp) > 0; }
static int primary(enum token n) { enum token nn; int res; if (n == EOI) return 0; /* missing expression */ if (n == LPAREN) { if ((nn = t_lex(*++t_wp)) == RPAREN) return 0; /* missing expression */ res = oexpr(nn); if (res != -42 && t_lex(*++t_wp) != RPAREN) return syntax(NULL, "closing paren expected"); return res; } if (t_wp_op && t_wp_op->op_type == UNOP) { /* unary expression */ if (*++t_wp == NULL) return syntax(t_wp_op->op_text, "argument expected"); switch (n) { case STREZ: return strlen(*t_wp) == 0; case STRNZ: return strlen(*t_wp) != 0; case FILTT: return isatty(getn(*t_wp)); default: return filstat(*t_wp, n); } } if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) { return binop(); } return strlen(*t_wp) > 0; }
/* * dfind - find a directory if specified by numeric (+n) argument */ static struct directory * dfind(Char *cp) { struct directory *dp; int i; Char *ep; if (*cp++ != '+') return (0); for (ep = cp; Isdigit(*ep); ep++) continue; if (*ep) return (0); i = getn(cp); if (i <= 0) return (0); for (dp = dcwd; i != 0; i--) { if ((dp = dp->di_prev) == &dhead) dp = dp->di_prev; if (dp == dcwd) stderror(ERR_NAME | ERR_DEEP); } return (dp); }
/* search for variable; if not found, return NULL or create globally */ struct tbl * isglobal(const char *n, bool docreate) { struct tbl *vp; union mksh_cchack vname; struct block *l = e->loc; int c; bool array; uint32_t h, val; /* * check to see if this is an array; * dereference namerefs; must come first */ vn = array_index_calc(n, &array, &val); h = hash(vn); c = (unsigned char)vn[0]; if (!ctype(c, C_ALPHX)) { if (array) errorf(Tbadsubst); vp = vtemp; vp->flag = DEFINED; vp->type = 0; vp->areap = ATEMP; if (ctype(c, C_DIGIT)) { if (getn(vn, &c)) { /* main.c:main_init() says 12 */ shf_snprintf(vp->name, 12, Tf_d, c); if (c <= l->argc) { /* setstr can't fail here */ setstr(vp, l->argv[c], KSH_RETURN_ERROR); } } else vp->name[0] = '\0'; vp->flag |= RDONLY; goto out; } vp->name[0] = c; vp->name[1] = '\0'; vp->flag |= RDONLY; if (vn[1] != '\0') goto out; vp->flag |= ISSET|INTEGER; switch (c) { case '$': vp->val.i = kshpid; break; case '!': /* if no job, expand to nothing */ if ((vp->val.i = j_async()) == 0) vp->flag &= ~(ISSET|INTEGER); break; case '?': vp->val.i = exstat & 0xFF; break; case '#': vp->val.i = l->argc; break; case '-': vp->flag &= ~INTEGER; vp->val.s = getoptions(); break; default: vp->flag &= ~(ISSET|INTEGER); } goto out; } l = varsearch(e->loc, &vp, vn, h); if (vp == NULL && docreate) vp = ktenter(&l->vars, vn, h); else docreate = false; if (vp != NULL) { if (array) vp = arraysearch(vp, val); if (docreate) { vp->flag |= DEFINED; if (special(vn)) vp->flag |= SPECIAL; } } out: last_lookup_was_array = array; if (vn != n) afree(vname.rw, ATEMP); return (vp); }
/* Get data from message up to the delimeter: * Copy data of the message to 'dta', starting from current position up to meeting 'delim' * @param: buf - buffer to which data will be copied * delim - the delimeter * @return: the number of bytes copied, if success * -1, if failed * * Notice: new character array will be allocated as needed and the space will be * deallocated at the time of the next call of this method, so 'buf' must be * a pointer to nothing and must not be deleted by caller */ int _condorInMsg::getPtr(void *&buf, char delim) { _condorDirPage *tempDir; int tempPkt, tempData; size_t n = 1; int size; tempDir = curDir; tempPkt = curPacket; tempData = curData; bool copy_needed = false; while(1) { char *msgbuf = &tempDir->dEntry[tempPkt].dGram[tempData]; size_t msgbufsize = tempDir->dEntry[tempPkt].dLen - tempData; char *delim_ptr = (char *)memchr(msgbuf,delim,msgbufsize); if( delim_ptr ) { n += delim_ptr - msgbuf; if( n == msgbufsize ) { // Need to copy the data in this case, because when // buffer is consumed by incrementCurData(), it will // be freed. copy_needed = true; } if( !copy_needed ) { // Special (common) case: the whole string is in one piece // so just return a pointer to it and skip the drudgery // of copying the bytes into another buffer. incrementCurData(n); buf = msgbuf; return n; } break; // found delim } copy_needed = true; // string spans multiple buffers n += msgbufsize; tempPkt++; tempData = 0; if(tempPkt >= SAFE_MSG_NO_OF_DIR_ENTRY) { if(!tempDir->nextDir) { return -1; } tempDir = tempDir->nextDir; tempPkt = 0; } else if(!tempDir->dEntry[tempPkt].dGram) { // was the last packet if( IsDebugVerbose(D_NETWORK) ) dprintf(D_NETWORK, "SafeMsg::getPtr: get to end & '%c' not found\n", delim); return -1; } } if( IsDebugVerbose(D_NETWORK) ) dprintf(D_NETWORK, "SafeMsg::_longMsg::getPtr: found delim = %c & length = %lu\n", delim, (unsigned long)n); if( n > tempBufLen ) { if(tempBuf) { free(tempBuf); } tempBuf = (char *)malloc(n); if(!tempBuf) { dprintf(D_ALWAYS, "getPtr, fail at malloc(%lu)\n", (unsigned long)n); tempBufLen = 0; return -1; } tempBufLen = n; } size = getn(tempBuf, n); buf = tempBuf; //cout << "\t\tInMsg::getPtr: " << (char *)buf << endl; return size; }
static double countscore(int w) { return getn(w); }
static double costscore(int w) { return getn(w)/((double)ddS.NWt[tscorek]) - (NwK[w]*ddS.NWt[tscorek]/((double)ddN.NT))/((double)ddN.NT); }
static double idfscore(int w) { if ( tscorek>=0 && ddP.phi ) return ddP.phi[tscorek][w]/NwK[w]; return (getn(w)+0.2)/(NwK[w]+0.2*ddN.T); }
static double idfscore(int w) { return (getn(w)+0.2)/(NwK[w]+0.2*ddN.T); }
virtual bool get(void *dst) { if (!compressed) return getBytes(dst, size)==size; return (getn(dst,1)==1); }
static int binop(shinstance *psh) { const char *opnd1, *opnd2; struct t_op const *op; opnd1 = *psh->t_wp; (void) t_lex(psh, *++psh->t_wp); op = psh->t_wp_op; if ((opnd2 = *++psh->t_wp) == NULL) syntax(psh, op->op_text, "argument expected"); switch (op->op_num) { case STREQ: return strcmp(opnd1, opnd2) == 0; case STRNE: return strcmp(opnd1, opnd2) != 0; case STRLT: return strcmp(opnd1, opnd2) < 0; case STRGT: return strcmp(opnd1, opnd2) > 0; case INTEQ: return getn(psh, opnd1) == getn(psh, opnd2); case INTNE: return getn(psh, opnd1) != getn(psh, opnd2); case INTGE: return getn(psh, opnd1) >= getn(psh, opnd2); case INTGT: return getn(psh, opnd1) > getn(psh, opnd2); case INTLE: return getn(psh, opnd1) <= getn(psh, opnd2); case INTLT: return getn(psh, opnd1) < getn(psh, opnd2); case FILNT: return newerf(psh, opnd1, opnd2); case FILOT: return olderf(psh, opnd1, opnd2); case FILEQ: return equalf(psh, opnd1, opnd2); default: sh_abort(psh); /* NOTREACHED */ return -1; } }
/* * Main procedure. Process arguments and then * transfer control to the main command processing loop * in the routine commands. We are entered as either "ex", "edit" or "vi" * and the distinction is made here. Actually, we are "vi" if * there is a 'v' in our name, and "edit" if there is a 'd' in our * name. For edit we just diddle options; for vi we actually * force an early visual command, setting the external initev so * the q command in visual doesn't give command mode. */ int main(int ac, char **av) { #if 0 char *erpath = EXSTRINGS; #endif register char *cp; register int c; bool recov = 0; bool ivis = any('v', av[0]); bool itag = 0; bool fast = 0; #ifdef TRACE register char *tracef; #endif /* * Immediately grab the tty modes so that we wont * get messed up if an interrupt comes in quickly. */ gTTY(1); normf = tty; #if 0 /* * For debugging take files out of . if name is a.out. * If a 'd' in our name, then set options for edit. */ if (av[0][0] == 'a') erpath += 9; #endif if (ivis) { options[MAGIC].odefault = value(MAGIC) = 0; options[BEAUTIFY].odefault = value(BEAUTIFY) = 1; } else if (any('d', av[0])) { value(OPEN) = 0; value(REPORT) = 1; value(MAGIC) = 0; } /* * Open the error message file. */ draino(); #if 0 erfile = open(erpath, 0); if (erfile < 0) { flush(); exit(1); } #endif pstop(); /* * Initialize interrupt handling. */ oldhup = signal(SIGHUP, SIG_IGN); if (oldhup == SIG_DFL) signal(SIGHUP, onhup); oldquit = signal(SIGQUIT, SIG_IGN); ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL; if (signal(SIGTERM, SIG_IGN) == SIG_DFL) signal(SIGTERM, onhup); /* * Initialize end of core pointers. * Normally we avoid breaking back to fendcore after each * file since this can be expensive (much core-core copying). * If your system can scatter load processes you could do * this as ed does, saving a little core, but it will probably * not often make much difference. */ #ifdef UNIX_SBRK fendcore = (line *) sbrk(0); endcore = fendcore - 2; #else # define LINELIMIT 0x8000 fendcore = malloc(LINELIMIT * sizeof(line *)); endcore = fendcore + LINELIMIT - 1; #endif /* * Process flag arguments. */ ac--, av++; while (ac && av[0][0] == '-') { c = av[0][1]; if (c == 0) { hush = 1; value(AUTOPRINT) = 0; fast++; } else switch (c) { #ifdef TRACE case 'T': if (av[0][2] == 0) tracef = "trace"; else { tracef = tttrace; tracef[8] = av[0][2]; if (tracef[8]) tracef[9] = av[0][3]; else tracef[9] = 0; } trace = fopen(tracef, "w"); if (trace == NULL) ex_printf("Trace create error\n"); setbuf(trace, tracbuf); break; #endif #ifdef LISP case 'l': value(LISP) = 1; value(SHOWMATCH) = 1; break; #endif case 'r': recov++; break; case 't': if (ac > 1 && av[1][0] != '-') { ac--, av++; itag = 1; /* BUG: should check for too long tag. */ CP(lasttag, av[0]); } break; case 'v': globp = ""; ivis = 1; break; default: smerror("Unknown option %s\n", av[0]); break; } ac--, av++; } if (ac && av[0][0] == '+') { firstln = getn(av[0] + 1); if (firstln == 0) firstln = 20000; ac--, av++; } /* * If we are doing a recover and no filename * was given, then execute an exrecover command with * the -r option to type out the list of saved file names. * Otherwise set the remembered file name to the first argument * file name so the "recover" initial command will find it. */ if (recov) { if (ac == 0) { die++; setrupt(); execl(EXRECOVER, "exrecover", "-r", NULL); filioerr(EXRECOVER); exit(1); } CP(savedfile, *av); av++, ac--; } /* * Initialize the argument list. */ argv0 = av; argc0 = ac; args0 = av[0]; erewind(); /* * Initialize a temporary file (buffer) and * set up terminal environment. Read user startup commands. */ init(); if (setexit() == 0) { setrupt(); intty = isatty(0); if (fast || !intty) setterm("dumb"); else { gettmode(); if ((cp = getenv("TERM")) != 0) setterm(cp); if ((cp = getenv("HOME")) != 0) source(strcat(strcpy(genbuf, cp), "/.exrc"), 1); } } /* * Initial processing. Handle tag, recover, and file argument * implied next commands. If going in as 'vi', then don't do * anything, just set initev so we will do it later (from within * visual). */ if (setexit() == 0) { if (recov) globp = "recover"; else if (itag) globp = ivis ? "tag" : "tag|p"; else if (argc) globp = "next"; if (ivis) initev = globp; else if (globp) { inglobal = 1; commands(1, 1); inglobal = 0; } } /* * Vi command... go into visual. * Strange... everything in vi usually happens * before we ever "start". */ if (ivis) { /* * Don't have to be upward compatible with stupidity * of starting editing at line $. */ if (dol > zero) dot = one; globp = "visual"; if (setexit() == 0) commands(1, 1); } /* * Clear out trash in state accumulated by startup, * and then do the main command loop for a normal edit. * If you quit out of a 'vi' command by doing Q or ^\, * you also fall through to here. */ ungetchar(0); globp = 0; initev = 0; setlastchar('\n'); setexit(); commands(0, 0); cleanup(1); return 0; }
/* * lookup variable (according to (set&LOCAL)), set its attributes * (INTEGER, RDONLY, EXPORT, TRACE, LJUST, RJUST, ZEROFIL, LCASEV, * UCASEV_AL), and optionally set its value if an assignment. */ struct tbl * typeset(const char *var, uint32_t set, uint32_t clr, int field, int base) { struct tbl *vp; struct tbl *vpbase, *t; char *tvar; const char *val; size_t len; bool vappend = false; enum namerefflag new_refflag = SRF_NOP; if ((set & (ARRAY | ASSOC)) == ASSOC) { new_refflag = SRF_ENABLE; set &= ~(ARRAY | ASSOC); } if ((clr & (ARRAY | ASSOC)) == ASSOC) { new_refflag = SRF_DISABLE; clr &= ~(ARRAY | ASSOC); } /* check for valid variable name, search for value */ val = skip_varname(var, false); if (val == var) { /* no variable name given */ return (NULL); } if (*val == '[') { if (new_refflag != SRF_NOP) errorf("%s: %s", var, "reference variable can't be an array"); len = array_ref_len(val); if (len == 0) return (NULL); /* * IMPORT is only used when the shell starts up and is * setting up its environment. Allow only simple array * references at this time since parameter/command * substitution is performed on the [expression] which * would be a major security hole. */ if (set & IMPORT) { size_t i; for (i = 1; i < len - 1; i++) if (!ksh_isdigit(val[i])) return (NULL); } val += len; } if (val[0] == '=') { strndupx(tvar, var, val - var, ATEMP); ++val; } else if (set & IMPORT) { /* environment invalid variable name or no assignment */ return (NULL); } else if (val[0] == '+' && val[1] == '=') { strndupx(tvar, var, val - var, ATEMP); val += 2; vappend = true; } else if (val[0] != '\0') { /* other invalid variable names (not from environment) */ return (NULL); } else { /* just varname with no value part nor equals sign */ strdupx(tvar, var, ATEMP); val = NULL; /* handle foo[*] => foo (whole array) mapping for R39b */ len = strlen(tvar); if (len > 3 && tvar[len - 3] == '[' && tvar[len - 2] == '*' && tvar[len - 1] == ']') tvar[len - 3] = '\0'; } if (new_refflag == SRF_ENABLE) { const char *qval, *ccp; /* bail out on 'nameref foo+=bar' */ if (vappend) errorf("appending not allowed for nameref"); /* find value if variable already exists */ if ((qval = val) == NULL) { varsearch(e->loc, &vp, tvar, hash(tvar)); if (vp == NULL) goto nameref_empty; qval = str_val(vp); } /* check target value for being a valid variable name */ ccp = skip_varname(qval, false); if (ccp == qval) { if (ksh_isdigit(qval[0])) { int c; if (getn(qval, &c)) goto nameref_rhs_checked; } else if (qval[1] == '\0') switch (qval[0]) { case '$': case '!': case '?': case '#': case '-': goto nameref_rhs_checked; } nameref_empty: errorf("%s: %s", var, "empty nameref target"); } len = (*ccp == '[') ? array_ref_len(ccp) : 0; if (ccp[len]) { /* * works for cases "no array", "valid array with * junk after it" and "invalid array"; in the * latter case, len is also 0 and points to '[' */ errorf("%s: %s", qval, "nameref target not a valid parameter name"); } nameref_rhs_checked: /* prevent nameref loops */ while (qval) { if (!strcmp(qval, tvar)) errorf("%s: %s", qval, "expression recurses on parameter"); varsearch(e->loc, &vp, qval, hash(qval)); qval = NULL; if (vp && ((vp->flag & (ARRAY | ASSOC)) == ASSOC)) qval = str_val(vp); } } /* prevent typeset from creating a local PATH/ENV/SHELL */ if (Flag(FRESTRICTED) && (strcmp(tvar, "PATH") == 0 || strcmp(tvar, "ENV") == 0 || strcmp(tvar, "SHELL") == 0)) errorf("%s: %s", tvar, "restricted"); innermost_refflag = new_refflag; vp = (set & LOCAL) ? local(tvar, tobool(set & LOCAL_COPY)) : global(tvar); if (new_refflag == SRF_DISABLE && (vp->flag & (ARRAY|ASSOC)) == ASSOC) vp->flag &= ~ASSOC; else if (new_refflag == SRF_ENABLE) { if (vp->flag & ARRAY) { struct tbl *a, *tmp; /* free up entire array */ for (a = vp->u.array; a; ) { tmp = a; a = a->u.array; if (tmp->flag & ALLOC) afree(tmp->val.s, tmp->areap); afree(tmp, tmp->areap); } vp->u.array = NULL; vp->flag &= ~ARRAY; } vp->flag |= ASSOC; } set &= ~(LOCAL|LOCAL_COPY); vpbase = (vp->flag & ARRAY) ? global(arrayname(tvar)) : vp; /* * only allow export flag to be set; AT&T ksh allows any * attribute to be changed which means it can be truncated or * modified (-L/-R/-Z/-i) */ if ((vpbase->flag & RDONLY) && (val || clr || (set & ~EXPORT))) /* XXX check calls - is error here ok by POSIX? */ errorfx(2, "read-only: %s", tvar); afree(tvar, ATEMP); /* most calls are with set/clr == 0 */ if (set | clr) { bool ok = true; /* * XXX if x[0] isn't set, there will be problems: need * to have one copy of attributes for arrays... */ for (t = vpbase; t; t = t->u.array) { bool fake_assign; char *s = NULL; char *free_me = NULL; fake_assign = (t->flag & ISSET) && (!val || t != vp) && ((set & (UCASEV_AL|LCASEV|LJUST|RJUST|ZEROFIL)) || ((t->flag & INTEGER) && (clr & INTEGER)) || (!(t->flag & INTEGER) && (set & INTEGER))); if (fake_assign) { if (t->flag & INTEGER) { s = str_val(t); free_me = NULL; } else { s = t->val.s + t->type; free_me = (t->flag & ALLOC) ? t->val.s : NULL; } t->flag &= ~ALLOC; } if (!(t->flag & INTEGER) && (set & INTEGER)) { t->type = 0; t->flag &= ~ALLOC; } t->flag = (t->flag | set) & ~clr; /* * Don't change base if assignment is to be * done, in case assignment fails. */ if ((set & INTEGER) && base > 0 && (!val || t != vp)) t->type = base; if (set & (LJUST|RJUST|ZEROFIL)) t->u2.field = field; if (fake_assign) { if (!setstr(t, s, KSH_RETURN_ERROR)) { /* * Somewhat arbitrary action * here: zap contents of * variable, but keep the flag * settings. */ ok = false; if (t->flag & INTEGER) t->flag &= ~ISSET; else { if (t->flag & ALLOC) afree(t->val.s, t->areap); t->flag &= ~(ISSET|ALLOC); t->type = 0; } } if (free_me) afree(free_me, t->areap); } } if (!ok) errorfz(); } if (val != NULL) { char *tval; if (vappend) { tval = shf_smprintf("%s%s", str_val(vp), val); val = tval; } else tval = NULL; if (vp->flag&INTEGER) { /* do not zero base before assignment */ setstr(vp, val, KSH_UNWIND_ERROR | 0x4); /* done after assignment to override default */ if (base > 0) vp->type = base; } else /* setstr can't fail (readonly check already done) */ setstr(vp, val, KSH_RETURN_ERROR | 0x4); if (tval != NULL) afree(tval, ATEMP); } /* only x[0] is ever exported, so use vpbase */ if ((vpbase->flag&EXPORT) && !(vpbase->flag&INTEGER) && vpbase->type == 0) exportprep(vpbase, (vpbase->flag&ISSET) ? vpbase->val.s : null); return (vp); }
/* * Search for variable, if not found create globally. */ struct tbl * global(const char *n) { struct block *l = e->loc; struct tbl *vp; int c; bool array; uint32_t h, val; /* * check to see if this is an array; * dereference namerefs; must come first */ n = array_index_calc(n, &array, &val); h = hash(n); c = (unsigned char)n[0]; if (!ksh_isalphx(c)) { if (array) errorf("bad substitution"); vp = &vtemp; vp->flag = DEFINED; vp->type = 0; vp->areap = ATEMP; *vp->name = c; if (ksh_isdigit(c)) { if (getn(n, &c) && (c <= l->argc)) /* setstr can't fail here */ setstr(vp, l->argv[c], KSH_RETURN_ERROR); vp->flag |= RDONLY; return (vp); } vp->flag |= RDONLY; if (n[1] != '\0') return (vp); vp->flag |= ISSET|INTEGER; switch (c) { case '$': vp->val.i = kshpid; break; case '!': /* if no job, expand to nothing */ if ((vp->val.i = j_async()) == 0) vp->flag &= ~(ISSET|INTEGER); break; case '?': vp->val.i = exstat & 0xFF; break; case '#': vp->val.i = l->argc; break; case '-': vp->flag &= ~INTEGER; vp->val.s = getoptions(); break; default: vp->flag &= ~(ISSET|INTEGER); } return (vp); } l = varsearch(e->loc, &vp, n, h); if (vp != NULL) return (array ? arraysearch(vp, val) : vp); vp = ktenter(&l->vars, n, h); if (array) vp = arraysearch(vp, val); vp->flag |= DEFINED; if (special(n)) vp->flag |= SPECIAL; return (vp); }
/*VARARGS 1*/ void execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout, int do_glob) { int forked = 0; const struct biltins * volatile bifunc; pid_t pid = 0; int pv[2]; sigset_t set; static sigset_t csigset; #ifdef VFORK static int onosigchld = 0; #endif /* VFORK */ static int nosigchld = 0; (void) &wanttty; (void) &forked; (void) &bifunc; if (t == 0) return; #ifdef WINNT_NATIVE { if ((varval(STRNTslowexec) == STRNULL) && !t->t_dcdr && !t->t_dcar && !t->t_dflg && !didfds && (intty || intact) && (t->t_dtyp == NODE_COMMAND) && !isbfunc(t)) { if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE) (void) Strcpy(t->t_dcom[0], t->t_dcom[0] + 1); Dfix(t); if (nt_try_fast_exec(t) == 0) return; } } #endif /* WINNT_NATIVE */ /* * Ed [email protected] & Dominic [email protected] * Sat Feb 25 03:13:11 PST 1995 * try implicit cd if we have a 1 word command */ if (implicit_cd && (intty || intact) && t->t_dcom && t->t_dcom[0] && t->t_dcom[0][0] && (blklen(t->t_dcom) == 1) && !noexec) { Char *sCName; struct stat stbuf; char *pathname; sCName = dollar(t->t_dcom[0]); if (sCName != NULL && sCName[0] == '~') { struct Strbuf buf = Strbuf_INIT; const Char *name_end; for (name_end = sCName + 1; *name_end != '\0' && *name_end != '/'; name_end++) continue; if (name_end != sCName + 1) { Char *name, *home; name = Strnsave(sCName + 1, name_end - (sCName + 1)); home = gethdir(name); if (home != NULL) { Strbuf_append(&buf, home); xfree(home); } else Strbuf_append(&buf, name); xfree(name); } else Strbuf_append(&buf, varval(STRhome)); Strbuf_append(&buf, name_end); xfree(sCName); sCName = Strbuf_finish(&buf); } pathname = short2str(sCName); xfree(sCName); /* if this is a dir, tack a "cd" on as the first arg */ if (pathname != NULL && ((stat(pathname, &stbuf) != -1 && S_ISDIR(stbuf.st_mode)) #ifdef WINNT_NATIVE || (pathname[0] && pathname[1] == ':' && pathname[2] == '\0') #endif /* WINNT_NATIVE */ )) { Char *vCD[2]; Char **ot_dcom = t->t_dcom; vCD[0] = Strsave(STRcd); vCD[1] = NULL; t->t_dcom = blkspl(vCD, ot_dcom); xfree(ot_dcom); if (implicit_cd > 1) { blkpr(t->t_dcom); xputchar( '\n' ); } } } /* * From: Michael Schroeder <*****@*****.**> * Don't check for wantty > 0... */ if (t->t_dflg & F_AMPERSAND) wanttty = 0; switch (t->t_dtyp) { case NODE_COMMAND: if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE) memmove(t->t_dcom[0], t->t_dcom[0] + 1, (Strlen(t->t_dcom[0] + 1) + 1) * sizeof (*t->t_dcom[0])); if ((t->t_dflg & F_REPEAT) == 0) Dfix(t); /* $ " ' \ */ if (t->t_dcom[0] == 0) { return; } /*FALLTHROUGH*/ case NODE_PAREN: #ifdef BACKPIPE if (t->t_dflg & F_PIPEIN) mypipe(pipein); #else /* !BACKPIPE */ if (t->t_dflg & F_PIPEOUT) mypipe(pipeout); #endif /* BACKPIPE */ /* * Must do << early so parent will know where input pointer should be. * If noexec then this is all we do. */ if (t->t_dflg & F_READ) { xclose(0); heredoc(t->t_dlef); if (noexec) xclose(0); } setcopy(STRstatus, STR0, VAR_READWRITE); /* * This mess is the necessary kludge to handle the prefix builtins: * nice, nohup, time. These commands can also be used by themselves, * and this is not handled here. This will also work when loops are * parsed. */ while (t->t_dtyp == NODE_COMMAND) if (eq(t->t_dcom[0], STRnice)) { if (t->t_dcom[1]) { if (strchr("+-", t->t_dcom[1][0])) { if (t->t_dcom[2]) { setname("nice"); t->t_nice = (unsigned char)getn(t->t_dcom[1]); lshift(t->t_dcom, 2); t->t_dflg |= F_NICE; } else break; } else { t->t_nice = 4; lshift(t->t_dcom, 1); t->t_dflg |= F_NICE; } } else break; } else if (eq(t->t_dcom[0], STRnohup)) { if (t->t_dcom[1]) { t->t_dflg |= F_NOHUP; lshift(t->t_dcom, 1); } else break; } else if (eq(t->t_dcom[0], STRhup)) { if (t->t_dcom[1]) { t->t_dflg |= F_HUP; lshift(t->t_dcom, 1); } else break; } else if (eq(t->t_dcom[0], STRtime)) { if (t->t_dcom[1]) { t->t_dflg |= F_TIME; lshift(t->t_dcom, 1); } else break; } #ifdef F_VER else if (eq(t->t_dcom[0], STRver)) if (t->t_dcom[1] && t->t_dcom[2]) { setname("ver"); t->t_systype = getv(t->t_dcom[1]); lshift(t->t_dcom, 2); t->t_dflg |= F_VER; } else break; #endif /* F_VER */ else break; /* is it a command */ if (t->t_dtyp == NODE_COMMAND) { /* * Check if we have a builtin function and remember which one. */ bifunc = isbfunc(t); if (noexec) { /* * Continue for builtins that are part of the scripting language */ if (bifunc == NULL) break; if (bifunc->bfunct != (bfunc_t)dobreak && bifunc->bfunct != (bfunc_t)docontin && bifunc->bfunct != (bfunc_t)doelse && bifunc->bfunct != (bfunc_t)doend && bifunc->bfunct != (bfunc_t)doforeach&& bifunc->bfunct != (bfunc_t)dogoto && bifunc->bfunct != (bfunc_t)doif && bifunc->bfunct != (bfunc_t)dorepeat && bifunc->bfunct != (bfunc_t)doswbrk && bifunc->bfunct != (bfunc_t)doswitch && bifunc->bfunct != (bfunc_t)dowhile && bifunc->bfunct != (bfunc_t)dozip) break; } } else { /* not a command */ bifunc = NULL; if (noexec) break; } /* * GrP Executing a command - run jobcmd hook * Don't run for builtins * Don't run if we're not in a tty * Don't run if we're not really executing */ /* * CR - Charles Ross Aug 2005 * added "isoutatty". * The new behavior is that the jobcmd won't be executed * if stdout (SHOUT) isnt attached to a tty.. IE when * redirecting, or using backquotes etc.. */ if (t->t_dtyp == NODE_COMMAND && !bifunc && !noexec && intty && isoutatty) { Char *cmd = unparse(t); cleanup_push(cmd, xfree); job_cmd(cmd); cleanup_until(cmd); } /* * We fork only if we are timed, or are not the end of a parenthesized * list and not a simple builtin function. Simple meaning one that is * not pipedout, niced, nohupped, or &'d. It would be nice(?) to not * fork in some of these cases. */ #ifdef BACKPIPE /* * Can't have NOFORK for the tail of a pipe - because it is not the * last command spawned (even if it is at the end of a parenthesised * list). */ if (t->t_dflg & F_PIPEIN) t->t_dflg &= ~(F_NOFORK); #else /* * "command | builtin" may cause major misbehaviour as noted in * in the BUGS file entry * Subject: Redirected input to built-in functions misbehaves badly * forking when the builtin is the end of the pipe corrects the * problem. */ if (bifunc && (t->t_dflg & F_PIPEIN)) t->t_dflg &= ~(F_NOFORK); #endif /* BACKPIPE */ /* * Prevent forking cd, pushd, popd, chdir cause this will cause the * shell not to change dir! (XXX: but only for nice?) */ if (bifunc && (bifunc->bfunct == (bfunc_t)dochngd || bifunc->bfunct == (bfunc_t)dopushd || bifunc->bfunct == (bfunc_t)dopopd)) t->t_dflg &= ~(F_NICE); if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 && (!bifunc || t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP | F_HUP)))) || /* * We have to fork for eval too. */ (bifunc && (t->t_dflg & F_PIPEIN) != 0 && bifunc->bfunct == (bfunc_t)doeval)) { #ifdef VFORK if (t->t_dtyp == NODE_PAREN || t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) #endif /* VFORK */ { forked++; /* * We need to block SIGCHLD here, so that if the process does * not die before we can set the process group */ if (wanttty >= 0 && !nosigchld) { sigemptyset(&set); sigaddset(&set, SIGCHLD); (void)sigprocmask(SIG_BLOCK, &set, &csigset); nosigchld = 1; } pid = pfork(t, wanttty); if (pid == 0 && nosigchld) { sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } else if (pid != 0 && (t->t_dflg & F_AMPERSAND)) backpid = pid; } #ifdef VFORK else { int ochild, osetintr, ohaderr, odidfds; int oSHIN, oSHOUT, oSHDIAG, oOLDSTD, otpgrp; int oisoutatty, oisdiagatty; sigset_t oset, ocsigset; # ifndef CLOSE_ON_EXEC int odidcch; # endif /* !CLOSE_ON_EXEC */ /* * Prepare for the vfork by saving everything that the child * corrupts before it exec's. Note that in some signal * implementations which keep the signal info in user space * (e.g. Sun's) it will also be necessary to save and restore * the current sigvec's for the signals the child touches * before it exec's. */ /* * Sooooo true... If this is a Sun, save the sigvec's. (Skip * Gilbrech - 11/22/87) */ # ifdef SAVESIGVEC struct sigaction savesv[NSIGSAVED]; sigset_t savesm; # endif /* SAVESIGVEC */ if (wanttty >= 0 && !nosigchld && !noexec) { sigemptyset(&set); sigaddset(&set, SIGCHLD); (void)sigprocmask(SIG_BLOCK, &set, &csigset); nosigchld = 1; } sigemptyset(&set); sigaddset(&set, SIGCHLD); sigaddset(&set, SIGINT); (void)sigprocmask(SIG_BLOCK, &set, &oset); ochild = child; osetintr = setintr; ohaderr = haderr; odidfds = didfds; # ifndef CLOSE_ON_EXEC odidcch = didcch; # endif /* !CLOSE_ON_EXEC */ oSHIN = SHIN; oSHOUT = SHOUT; oSHDIAG = SHDIAG; oOLDSTD = OLDSTD; otpgrp = tpgrp; oisoutatty = isoutatty; oisdiagatty = isdiagatty; ocsigset = csigset; onosigchld = nosigchld; Vsav = Vdp = 0; Vexpath = 0; Vt = 0; # ifdef SAVESIGVEC savesigvec(savesv, savesm); # endif /* SAVESIGVEC */ if (use_fork) pid = fork(); else pid = vfork(); if (pid < 0) { # ifdef SAVESIGVEC restoresigvec(savesv, savesm); # endif /* SAVESIGVEC */ sigprocmask(SIG_SETMASK, &oset, NULL); stderror(ERR_NOPROC); } forked++; if (pid) { /* parent */ # ifdef SAVESIGVEC restoresigvec(savesv, savesm); # endif /* SAVESIGVEC */ child = ochild; setintr = osetintr; haderr = ohaderr; didfds = odidfds; SHIN = oSHIN; # ifndef CLOSE_ON_EXEC didcch = odidcch; # endif /* !CLOSE_ON_EXEC */ SHOUT = oSHOUT; SHDIAG = oSHDIAG; OLDSTD = oOLDSTD; tpgrp = otpgrp; isoutatty = oisoutatty; isdiagatty = oisdiagatty; csigset = ocsigset; nosigchld = onosigchld; xfree(Vsav); Vsav = 0; xfree(Vdp); Vdp = 0; xfree(Vexpath); Vexpath = 0; blk_cleanup(Vt); Vt = 0; /* this is from pfork() */ palloc(pid, t); sigprocmask(SIG_SETMASK, &oset, NULL); } else { /* child */ /* this is from pfork() */ pid_t pgrp; int ignint = 0; if (nosigchld) { sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } if (setintr) ignint = (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) || (gointr && eq(gointr, STRminus)); pgrp = pcurrjob ? pcurrjob->p_jobid : getpid(); child++; if (setintr) { setintr = 0; /* * casts made right for SunOS 4.0 by Douglas C. Schmidt * <*****@*****.**> * (thanks! -- PWP) * * ignint ifs cleaned by Johan Widen <[email protected]> * (thanks again) */ if (ignint) { (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); } else { (void) signal(SIGINT, vffree); (void) signal(SIGQUIT, SIG_DFL); } # ifdef BSDJOBS if (wanttty >= 0) { (void) signal(SIGTSTP, SIG_DFL); (void) signal(SIGTTIN, SIG_DFL); (void) signal(SIGTTOU, SIG_DFL); } # endif /* BSDJOBS */ sigaction(SIGTERM, &parterm, NULL); } else if (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) { (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); } pgetty(wanttty, pgrp); if (t->t_dflg & F_NOHUP) (void) signal(SIGHUP, SIG_IGN); if (t->t_dflg & F_HUP) (void) signal(SIGHUP, SIG_DFL); if (t->t_dflg & F_NICE) { int nval = SIGN_EXTEND_CHAR(t->t_nice); # if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno) stderror(ERR_SYSTEM, "setpriority", strerror(errno)); # else /* !HAVE_SETPRIORITY || !PRIO_PROCESS */ (void) nice(nval); # endif /* HAVE_SETPRIORITY && PRIO_PROCESS */ } # ifdef F_VER if (t->t_dflg & F_VER) { tsetenv(STRSYSTYPE, t->t_systype ? STRbsd43 : STRsys53); dohash(NULL, NULL); } # endif /* F_VER */ } } #endif /* VFORK */ } if (pid != 0) { /* * It would be better if we could wait for the whole job when we * knew the last process had been started. Pwait, in fact, does * wait for the whole job anyway, but this test doesn't really * express our intentions. */ #ifdef BACKPIPE if (didfds == 0 && t->t_dflg & F_PIPEOUT) { xclose(pipeout[0]); xclose(pipeout[1]); } if ((t->t_dflg & F_PIPEIN) != 0) break; #else /* !BACKPIPE */ if (didfds == 0 && t->t_dflg & F_PIPEIN) { xclose(pipein[0]); xclose(pipein[1]); } if ((t->t_dflg & F_PIPEOUT) != 0) break; #endif /* BACKPIPE */ if (nosigchld) { sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } if ((t->t_dflg & F_AMPERSAND) == 0) pwait(); break; } doio(t, pipein, pipeout); #ifdef BACKPIPE if (t->t_dflg & F_PIPEIN) { xclose(pipein[0]); xclose(pipein[1]); } #else /* !BACKPIPE */ if (t->t_dflg & F_PIPEOUT) { xclose(pipeout[0]); xclose(pipeout[1]); } #endif /* BACKPIPE */ /* * Perform a builtin function. If we are not forked, arrange for * possible stopping */ if (bifunc) { if (forked) { func(t, bifunc); exitstat(); } else { jmp_buf_t oldexit; int ohaderr = haderr; getexit(oldexit); if (setexit() == 0) func(t, bifunc); resexit(oldexit); haderr = ohaderr; if (adrof(STRprintexitvalue)) { int rv = getn(varval(STRstatus)); if (rv != 0) xprintf(CGETS(17, 2, "Exit %d\n"), rv); } } break; } if (t->t_dtyp != NODE_PAREN) { doexec(t, do_glob); /* NOTREACHED */ } /* * For () commands must put new 0,1,2 in FSH* and recurse */ if ((OLDSTD = dcopy(0, FOLDSTD)) >= 0) (void)close_on_exec(OLDSTD, 1); if ((SHOUT = dcopy(1, FSHOUT)) >= 0) { (void)close_on_exec(SHOUT, 1); isoutatty = isatty(SHOUT); } if ((SHDIAG = dcopy(2, FSHDIAG)) >= 0) { (void)close_on_exec(SHDIAG, 1); isdiagatty = isatty(SHDIAG); } xclose(SHIN); SHIN = -1; #ifndef CLOSE_ON_EXEC didcch = 0; #else (void) close_on_exec(FSHOUT, 1); (void) close_on_exec(FSHDIAG, 1); (void) close_on_exec(FOLDSTD, 1); #endif /* !CLOSE_ON_EXEC */ didfds = 0; wanttty = -1; t->t_dspr->t_dflg |= t->t_dflg & (F_NOINTERRUPT | F_BACKQ); execute(t->t_dspr, wanttty, NULL, NULL, do_glob); exitstat(); case NODE_PIPE: #ifdef BACKPIPE t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT | F_BACKQ)); execute(t->t_dcdr, wanttty, pv, pipeout, do_glob); t->t_dcar->t_dflg |= F_PIPEOUT | (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT | F_BACKQ)); execute(t->t_dcar, wanttty, pipein, pv, do_glob); #else /* !BACKPIPE */ t->t_dcar->t_dflg |= F_PIPEOUT | (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT | F_BACKQ)); execute(t->t_dcar, wanttty, pipein, pv, do_glob); t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT | F_BACKQ)); execute(t->t_dcdr, wanttty, pv, pipeout, do_glob); #endif /* BACKPIPE */ break; case NODE_LIST: if (t->t_dcar) { t->t_dcar->t_dflg |= t->t_dflg & (F_NOINTERRUPT | F_BACKQ); execute(t->t_dcar, wanttty, NULL, NULL, do_glob); /* * In strange case of A&B make a new job after A */ if (t->t_dcar->t_dflg & F_AMPERSAND && t->t_dcdr && (t->t_dcdr->t_dflg & F_AMPERSAND) == 0) pendjob(); } if (t->t_dcdr) { t->t_dcdr->t_dflg |= t->t_dflg & (F_NOFORK | F_NOINTERRUPT | F_BACKQ); execute(t->t_dcdr, wanttty, NULL, NULL, do_glob); } break; case NODE_OR: case NODE_AND: if (t->t_dcar) { t->t_dcar->t_dflg |= t->t_dflg & (F_NOINTERRUPT | F_BACKQ); execute(t->t_dcar, wanttty, NULL, NULL, do_glob); if ((getn(varval(STRstatus)) == 0) != (t->t_dtyp == NODE_AND)) { return; } } if (t->t_dcdr) { t->t_dcdr->t_dflg |= t->t_dflg & (F_NOFORK | F_NOINTERRUPT | F_BACKQ); execute(t->t_dcdr, wanttty, NULL, NULL, do_glob); } break; default: break; } /* * Fall through for all breaks from switch * * If there will be no more executions of this command, flush all file * descriptors. Places that turn on the F_REPEAT bit are responsible for * doing donefds after the last re-execution */ if (didfds && !(t->t_dflg & F_REPEAT)) donefds(); }
void execute(struct command *t, int wtty, int *pipein, int *pipeout) { static sigset_t csigset, ocsigset; static int nosigchld = 0, onosigchld = 0; volatile int wanttty = wtty; struct biltins * volatile bifunc; int pv[2], pid; sigset_t nsigset; int forked; UNREGISTER(forked); UNREGISTER(bifunc); UNREGISTER(wanttty); forked = 0; pid = 0; if (t == 0) return; if (t->t_dflg & F_AMPERSAND) wanttty = 0; switch (t->t_dtyp) { case NODE_COMMAND: if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE) (void)Strcpy(t->t_dcom[0], t->t_dcom[0] + 1); if ((t->t_dflg & F_REPEAT) == 0) Dfix(t); /* $ " ' \ */ if (t->t_dcom[0] == 0) return; /* FALLTHROUGH */ case NODE_PAREN: if (t->t_dflg & F_PIPEOUT) mypipe(pipeout); /* * Must do << early so parent will know where input pointer should be. * If noexec then this is all we do. */ if (t->t_dflg & F_READ) { (void)close(0); heredoc(t->t_dlef); if (noexec) (void)close(0); } set(STRstatus, Strsave(STR0)); /* * This mess is the necessary kludge to handle the prefix builtins: * nice, nohup, time. These commands can also be used by themselves, * and this is not handled here. This will also work when loops are * parsed. */ while (t->t_dtyp == NODE_COMMAND) if (eq(t->t_dcom[0], STRnice)) { if (t->t_dcom[1]) { if (strchr("+-", t->t_dcom[1][0])) { if (t->t_dcom[2]) { setname("nice"); t->t_nice = getn(t->t_dcom[1]); lshift(t->t_dcom, 2); t->t_dflg |= F_NICE; } else break; } else { t->t_nice = 4; lshift(t->t_dcom, 1); t->t_dflg |= F_NICE; } } else break; } else if (eq(t->t_dcom[0], STRnohup)) { if (t->t_dcom[1]) { t->t_dflg |= F_NOHUP; lshift(t->t_dcom, 1); } else break; } else if (eq(t->t_dcom[0], STRtime)) { if (t->t_dcom[1]) { t->t_dflg |= F_TIME; lshift(t->t_dcom, 1); } else break; } else break; /* is it a command */ if (t->t_dtyp == NODE_COMMAND) { /* * Check if we have a builtin function and remember which one. */ bifunc = isbfunc(t); if (noexec && bifunc != NULL) { /* * Continue for builtins that are part of the scripting language */ if (bifunc->bfunct != dobreak && bifunc->bfunct != docontin && bifunc->bfunct != doelse && bifunc->bfunct != doend && bifunc->bfunct != doforeach && bifunc->bfunct != dogoto && bifunc->bfunct != doif && bifunc->bfunct != dorepeat && bifunc->bfunct != doswbrk && bifunc->bfunct != doswitch && bifunc->bfunct != dowhile && bifunc->bfunct != dozip) break; } } else { /* not a command */ bifunc = NULL; if (noexec) break; } /* * We fork only if we are timed, or are not the end of a parenthesized * list and not a simple builtin function. Simple meaning one that is * not pipedout, niced, nohupped, or &'d. It would be nice(?) to not * fork in some of these cases. */ /* * Prevent forking cd, pushd, popd, chdir cause this will cause the * shell not to change dir! */ if (bifunc && (bifunc->bfunct == dochngd || bifunc->bfunct == dopushd || bifunc->bfunct == dopopd)) t->t_dflg &= ~(F_NICE); if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 && (!bifunc || t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP)))) || /* * We have to fork for eval too. */ (bifunc && (t->t_dflg & (F_PIPEIN | F_PIPEOUT)) != 0 && bifunc->bfunct == doeval)) { if (t->t_dtyp == NODE_PAREN || t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) { forked++; /* * We need to block SIGCHLD here, so that if the process does * not die before we can set the process group */ if (wanttty >= 0 && !nosigchld) { sigemptyset(&nsigset); (void)sigaddset(&nsigset, SIGCHLD); (void)sigprocmask(SIG_BLOCK, &nsigset, &csigset); nosigchld = 1; } pid = pfork(t, wanttty); if (pid == 0 && nosigchld) { (void)sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } else if (pid != 0 && (t->t_dflg & F_AMPERSAND)) backpid = pid; } else { int ochild, osetintr, ohaderr, odidfds; int oSHIN, oSHOUT, oSHERR, oOLDSTD, otpgrp; sigset_t osigset; /* * Prepare for the vfork by saving everything that the child * corrupts before it exec's. Note that in some signal * implementations which keep the signal info in user space * (e.g. Sun's) it will also be necessary to save and restore * the current sigaction's for the signals the child touches * before it exec's. */ if (wanttty >= 0 && !nosigchld && !noexec) { sigemptyset(&nsigset); (void)sigaddset(&nsigset, SIGCHLD); (void)sigprocmask(SIG_BLOCK, &nsigset, &csigset); nosigchld = 1; } sigemptyset(&nsigset); (void)sigaddset(&nsigset, SIGCHLD); (void)sigaddset(&nsigset, SIGINT); (void)sigprocmask(SIG_BLOCK, &nsigset, &osigset); ochild = child; osetintr = setintr; ohaderr = haderr; odidfds = didfds; oSHIN = SHIN; oSHOUT = SHOUT; oSHERR = SHERR; oOLDSTD = OLDSTD; otpgrp = tpgrp; ocsigset = csigset; onosigchld = nosigchld; Vsav = Vdp = 0; Vexpath = 0; Vt = 0; pid = vfork(); if (pid < 0) { (void)sigprocmask(SIG_SETMASK, &osigset, NULL); stderror(ERR_NOPROC); } forked++; if (pid) { /* parent */ child = ochild; setintr = osetintr; haderr = ohaderr; didfds = odidfds; SHIN = oSHIN; SHOUT = oSHOUT; SHERR = oSHERR; OLDSTD = oOLDSTD; tpgrp = otpgrp; csigset = ocsigset; nosigchld = onosigchld; xfree((ptr_t) Vsav); Vsav = 0; xfree((ptr_t) Vdp); Vdp = 0; xfree((ptr_t) Vexpath); Vexpath = 0; blkfree((Char **) Vt); Vt = 0; /* this is from pfork() */ palloc(pid, t); (void)sigprocmask(SIG_SETMASK, &osigset, NULL); } else { /* child */ /* this is from pfork() */ int pgrp; int ignint = 0; if (nosigchld) { (void)sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } if (setintr) ignint = (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) || (gointr && eq(gointr, STRminus)); pgrp = pcurrjob ? pcurrjob->p_jobid : getpid(); child++; if (setintr) { setintr = 0; if (ignint) { (void)signal(SIGINT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); } else { (void)signal(SIGINT, vffree); (void)signal(SIGQUIT, SIG_DFL); } if (wanttty >= 0) { (void)signal(SIGTSTP, SIG_DFL); (void)signal(SIGTTIN, SIG_DFL); (void)signal(SIGTTOU, SIG_DFL); } (void)signal(SIGTERM, parterm); } else if (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) { (void)signal(SIGINT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); } pgetty(wanttty, pgrp); if (t->t_dflg & F_NOHUP) (void)signal(SIGHUP, SIG_IGN); if (t->t_dflg & F_NICE) (void)setpriority(PRIO_PROCESS, 0, t->t_nice); } } } if (pid != 0) { /* * It would be better if we could wait for the whole job when we * knew the last process had been started. Pwait, in fact, does * wait for the whole job anyway, but this test doesn't really * express our intentions. */ if (didfds == 0 && t->t_dflg & F_PIPEIN) { (void)close(pipein[0]); (void)close(pipein[1]); } if ((t->t_dflg & F_PIPEOUT) == 0) { if (nosigchld) { (void)sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } if ((t->t_dflg & F_AMPERSAND) == 0) pwait(); } break; } doio(t, pipein, pipeout); if (t->t_dflg & F_PIPEOUT) { (void)close(pipeout[0]); (void)close(pipeout[1]); } /* * Perform a builtin function. If we are not forked, arrange for * possible stopping */ if (bifunc) { func(t, bifunc); if (forked) exitstat(); break; } if (t->t_dtyp != NODE_PAREN) doexec(NULL, t); /* * For () commands must put new 0,1,2 in FSH* and recurse */ (void) ioctl(OLDSTD = dcopy(0, FOLDSTD), FIOCLEX, NULL); (void) ioctl(SHOUT = dcopy(1, FSHOUT), FIOCLEX, NULL); (void) ioctl(SHERR = dcopy(2, FSHERR), FIOCLEX, NULL); (void) close(SHIN); SHIN = -1; didfds = 0; wanttty = -1; t->t_dspr->t_dflg |= t->t_dflg & F_NOINTERRUPT; execute(t->t_dspr, wanttty, NULL, NULL); exitstat(); /* NOTREACHED */ case NODE_PIPE: t->t_dcar->t_dflg |= F_PIPEOUT | (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT)); execute(t->t_dcar, wanttty, pipein, pv); t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT)); if (wanttty > 0) wanttty = 0; /* got tty already */ execute(t->t_dcdr, wanttty, pv, pipeout); break; case NODE_LIST: if (t->t_dcar) { t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT; execute(t->t_dcar, wanttty, NULL, NULL); /* * In strange case of A&B make a new job after A */ if (t->t_dcar->t_dflg & F_AMPERSAND && t->t_dcdr && (t->t_dcdr->t_dflg & F_AMPERSAND) == 0) pendjob(); } if (t->t_dcdr) { t->t_dcdr->t_dflg |= t->t_dflg & (F_NOFORK | F_NOINTERRUPT); execute(t->t_dcdr, wanttty, NULL, NULL); } break; case NODE_OR: case NODE_AND: if (t->t_dcar) { t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT; execute(t->t_dcar, wanttty, NULL, NULL); if ((getn(value(STRstatus)) == 0) != (t->t_dtyp == NODE_AND)) return; } if (t->t_dcdr) { t->t_dcdr->t_dflg |= t->t_dflg & (F_NOFORK | F_NOINTERRUPT); execute(t->t_dcdr, wanttty, NULL, NULL); } break; } /* * Fall through for all breaks from switch * * If there will be no more executions of this command, flush all file * descriptors. Places that turn on the F_REPEAT bit are responsible for * doing donefds after the last re-execution */ if (didfds && !(t->t_dflg & F_REPEAT)) donefds(); }
char *TFileList::getfilename () { return getn (pos); }
void browse_main() { /* 文件浏览器主函数 */ char ncat[64], workdir[64] = "\\\\fls0"; // 当前目录 f_name *a=get_file_list("\\\\fls0\\*.*"); // 存储文件列表的二维数组 int pos=0,firstn=0; // 列表光标位置、列表下移的行数 unsigned int key; char subdir_fn[32]; // 供接收子目录文件名输入的缓冲区 FONTCHARACTER fname[64]; int handle = 0; DefineStatusAreaFlags(3, 0x01 | 0x02 | 0x100, 0, 0); beg: if (a) qsort(a, getn(a), sizeof(char *), cmp); font16 = open_font("\\\\fls0\\24PX.hzk"); select_font(font16); draw_browser(workdir,firstn,pos,a); // 绘制浏览器界面 close_font(font16); // 显示当前工作目录于状态栏 if (strcmp(workdir, "\\\\fls0") == 0) DefineStatusMessage("", 0, 0, 0); else { memset(ncat, 0, sizeof(ncat)); GetDisplayDirName(workdir, ncat); DefineStatusMessage(ncat, 0, 0, 0); } while (1) { GetKey(&key); switch (key) { case KEY_CTRL_UP: // 光标上移 if (a) { aa(&pos,&firstn,getn(a)); goto beg; } break; case KEY_CTRL_DOWN: // 光标下移 if (a) { bb(&pos,&firstn,getn(a)); goto beg; } break; case KEY_CTRL_F6: // 显示关于信息 Disp_About(); goto beg; break; case KEY_CTRL_F1: // 打开光标位置的文件 case KEY_CTRL_EXE: if (a) // 如果文件列表不为空 { if (strchr(a[pos+firstn].name,'[')) // 如果打开的是文件夹 { memset(ncat,0,sizeof(ncat)); //strcat(ncat,"\\\\fls0\\"); strcat(ncat, workdir); strcat(ncat, "\\"); strcat(ncat, ++a[pos+firstn].name); memset(workdir, 0, sizeof(workdir)); strcpy(workdir, ncat); strcat(ncat, "\\*.*"); // 解析出文件夹名称 a=get_file_list(ncat); // 浏览该文件夹 pos=0; firstn=0; // 列表初始化 goto beg; } else // 如果打开的是文本文件 { memset(ncat,0,sizeof(ncat)); strcpy(ncat,workdir); strcat(ncat,"\\"); strcat(ncat,a[pos+firstn].name); // 解析出文件名称 iRead_main(ncat); // 启动阅读器 goto beg; } } break; case KEY_CTRL_F2: // 根据输入的文件名打开文件 memset(subdir_fn, 0, sizeof(subdir_fn)); if (Subdir_Open(subdir_fn)) { memset(ncat, 0, sizeof(ncat)); strcpy(ncat, workdir); strcat(ncat, "\\"); strcat(ncat, subdir_fn); // 连接上输入的文件名字 strcat(ncat, ".txt"); char_to_font(ncat, fname); handle = Bfile_OpenFile_OS(fname,0); if (handle <= 0) // 如果文件未找到 { Disp_FileNotFound(); MsgBoxPop(); goto beg; break; } MsgBoxPop(); Bfile_CloseFile_OS(handle); // 重新绘制浏览器界面 font16 = open_font("\\\\fls0\\24PX.hzk"); select_font(font16); draw_browser(workdir, firstn, pos, a); close_font(font16); // 启动阅读器 iRead_main(ncat); } goto beg; break; case KEY_CTRL_EXIT: // 从文件夹返回根目录 if (strcmp(workdir,"\\\\fls0")!=0) // 如果当前在文件夹内 { memset(ncat,0,sizeof(ncat)); strncpy(ncat,workdir,strlen(workdir)-strlen(strrchr(workdir,'\\'))); memset(workdir,0,sizeof(workdir)); strcpy(workdir,ncat); strcat(ncat,"\\*.*"); // 解析出上一级目录的名称 a=get_file_list(ncat); // 浏览该文件夹 pos=0;firstn=0; // 初始化列表 goto beg; } break; } } }
char *TFileList::getabsolute (int n) { return getabsolute (getn(n)); }
/* * Karl Kleinpaste, 21oct1983. * Set up a one-word alias command, for use for special things. * This code is based on the mainline of process(). */ void aliasrun(int cnt, Char *s1, Char *s2) { struct wordent w, *new1, *new2; /* for holding alias name */ struct command *t = NULL; jmp_buf_t osetexit; int status; size_t omark; getexit(osetexit); if (seterr) { xfree(seterr); seterr = NULL; /* don't repeatedly print err msg. */ } w.word = STRNULL; new1 = xcalloc(1, sizeof w); new1->word = Strsave(s1); if (cnt == 1) { /* build a lex list with one word. */ w.next = w.prev = new1; new1->next = new1->prev = &w; } else { /* build a lex list with two words. */ new2 = xcalloc(1, sizeof w); new2->word = Strsave(s2); w.next = new2->prev = new1; new1->next = w.prev = new2; new1->prev = new2->next = &w; } cleanup_push(&w, lex_cleanup); /* Save the old status */ status = getn(varval(STRstatus)); /* expand aliases like process() does. */ alias(&w); /* build a syntax tree for the command. */ t = syntax(w.next, &w, 0); cleanup_push(t, syntax_cleanup); if (seterr) stderror(ERR_OLD); psavejob(); cleanup_push(&cnt, psavejob_cleanup); /* cnt is used only as a marker */ /* catch any errors here */ omark = cleanup_push_mark(); if (setexit() == 0) /* execute the parse tree. */ /* * From: Michael Schroeder <*****@*****.**> * was execute(t, tpgrp); */ execute(t, tpgrp > 0 ? tpgrp : -1, NULL, NULL, TRUE); /* reset the error catcher to the old place */ cleanup_pop_mark(omark); resexit(osetexit); if (haderr) { haderr = 0; /* * Either precmd, or cwdcmd, or periodic had an error. Call it again so * that it is removed */ if (precmd_active) precmd(); if (postcmd_active) postcmd(); #ifdef notdef /* * XXX: On the other hand, just interrupting them causes an error too. * So if we hit ^C in the middle of cwdcmd or periodic the alias gets * removed. We don't want that. Note that we want to remove precmd * though, cause that could lead into an infinite loop. This should be * fixed correctly, but then haderr should give us the whole exit * status not just true or false. */ else if (cwdcmd_active) cwd_cmd(); else if (beepcmd_active) beep_cmd(); else if (periodic_active) period_cmd(); #endif /* notdef */ } cleanup_until(&w); pendjob(); /* Restore status */ setv(STRstatus, putn((tcsh_number_t)status), VAR_READWRITE); }
bool manage::go(){ int t=1<<2;int id=2;char u[8]={0};flash a; while(id<31){ if(t&user) if(only&&robot&(1<<id))//机器 { man.control=control[id]; int dir = man.AI_c(); setdir(dir,id); man.control->SETDIR(dir); u[0]=id; int w = man.control->run(); switch (w) { //case 1:eat();break; case 0:break; case 1:break;//食物 case WALL: leave(id); u[0]=id; a.n=2; a.DoModal(); dlg.Create(IDD_NET); dlg.ShowWindow(SW_SHOW); return false; break;//撞墙死 default: a.DoModal(); dlg.Create(IDD_NET); dlg.ShowWindow(SW_SHOW); leave(id);u[0]=id; //dlg.sendmessage('5',u); return false; } } else//网络部分 { u[0]=id+'0'; //::Sleep(10); /*if(dlg.server&&!only) dlg.sendmessage('7',u);*/ //::Sleep(20); int w=control[id]->run(); //*****************************************网络部分添加 //dlg.sendmessage(); char tt[4] = { 0 }; tt[0] =id+'0'; tt[1]='0'+control[id]->head.x; tt[2]='0'+control[id]->head.y; //m.setdir(dir,id); dlg.sendmessage('9',tt); //***************************************** Sleep(20); switch (w) { //case 1:eat();break; case 0:break; case 1: dlg.sendmessage('7',u); break;//食物 case WALL: leave(id); u[0]=id+'0'; if(!only) dlg.sendmessage('5',u);//死亡 return false; //撞墙死 default: leave(id); u[0]=id+'0'; if(!only) dlg.sendmessage('5',u); if (w&(1 << id)){ ; }//自杀 else if (t<0){ ; }//和别人一起死 else { int kill = getn(w); }//被kill杀 return false; } } id++;t=t<<1; } return 1; }
static void update_vars(Char *vp) { if (eq(vp, STRpath)) { struct varent *p = adrof(STRpath); if (p == NULL) stderror(ERR_NAME | ERR_UNDVAR); else { exportpath(p->vec); dohash(NULL, NULL); } } else if (eq(vp, STRnoclobber)) { struct varent *p = adrof(STRnoclobber); if (p == NULL) stderror(ERR_NAME | ERR_UNDVAR); else no_clobber = set_noclobber(p->vec); } else if (eq(vp, STRhistchars)) { Char *pn = varval(vp); HIST = *pn++; if (HIST) HISTSUB = *pn; else HISTSUB = HIST; } else if (eq(vp, STRpromptchars)) { Char *pn = varval(vp); PRCH = *pn++; if (PRCH) PRCHROOT = *pn; else PRCHROOT = PRCH; } else if (eq(vp, STRhistlit)) { HistLit = 1; } else if (eq(vp, STRuser)) { tsetenv(STRKUSER, varval(vp)); tsetenv(STRLOGNAME, varval(vp)); } else if (eq(vp, STRgroup)) { tsetenv(STRKGROUP, varval(vp)); } else if (eq(vp, STRwordchars)) { word_chars = varval(vp); } else if (eq(vp, STRloginsh)) { loginsh = 1; } else if (eq(vp, STRanyerror)) { anyerror = 1; } else if (eq(vp, STRsymlinks)) { Char *pn = varval(vp); if (eq(pn, STRignore)) symlinks = SYM_IGNORE; else if (eq(pn, STRexpand)) symlinks = SYM_EXPAND; else if (eq(pn, STRchase)) symlinks = SYM_CHASE; else symlinks = 0; } else if (eq(vp, STRterm)) { Char *cp = varval(vp); tsetenv(STRKTERM, cp); #ifdef DOESNT_WORK_RIGHT cp = getenv("TERMCAP"); if (cp && (*cp != '/')) /* if TERMCAP and not a path */ Unsetenv(STRTERMCAP); #endif /* DOESNT_WORK_RIGHT */ GotTermCaps = 0; if (noediting && Strcmp(cp, STRnetwork) != 0 && Strcmp(cp, STRunknown) != 0 && Strcmp(cp, STRdumb) != 0) { editing = 1; noediting = 0; setNS(STRedit); } ed_Init(); /* reset the editor */ } else if (eq(vp, STRhome)) { Char *cp, *canon; cp = Strsave(varval(vp)); /* get the old value back */ cleanup_push(cp, xfree); /* * convert to cononical pathname (possibly resolving symlinks) */ canon = dcanon(cp, cp); cleanup_ignore(cp); cleanup_until(cp); cleanup_push(canon, xfree); setcopy(vp, canon, VAR_READWRITE); /* have to save the new val */ /* and now mirror home with HOME */ tsetenv(STRKHOME, canon); /* fix directory stack for new tilde home */ dtilde(); cleanup_until(canon); } else if (eq(vp, STRedit)) { editing = 1; noediting = 0; /* PWP: add more stuff in here later */ } else if (eq(vp, STRvimode)) { VImode = 1; update_wordchars(); } else if (eq(vp, STRshlvl)) { tsetenv(STRKSHLVL, varval(vp)); } else if (eq(vp, STRignoreeof)) { Char *cp; numeof = 0; for ((cp = varval(STRignoreeof)); cp && *cp; cp++) { if (!Isdigit(*cp)) { numeof = 0; break; } numeof = numeof * 10 + *cp - '0'; } if (numeof <= 0) numeof = 26; /* Sanity check */ } else if (eq(vp, STRbackslash_quote)) { bslash_quote = 1; } else if (eq(vp, STRcompat_expr)) { compat_expr = 1; } else if (eq(vp, STRdirstack)) { dsetstack(); } else if (eq(vp, STRrecognize_only_executables)) { tw_cmd_free(); } else if (eq(vp, STRkillring)) { SetKillRing((int)getn(varval(vp))); } else if (eq(vp, STRhistory)) { sethistory((int)getn(varval(vp))); } #ifndef HAVENOUTMP else if (eq(vp, STRwatch)) { resetwatch(); } #endif /* HAVENOUTMP */ else if (eq(vp, STRimplicitcd)) { implicit_cd = ((eq(varval(vp), STRverbose)) ? 2 : 1); } else if (eq(vp, STRcdtohome)) { cdtohome = 1; } #ifdef COLOR_LS_F else if (eq(vp, STRcolor)) { set_color_context(); } #endif /* COLOR_LS_F */ #if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) else if(eq(vp, CHECK_MBYTEVAR) || eq(vp, STRnokanji)) { update_dspmbyte_vars(); } #endif #ifdef NLS_CATALOGS else if (eq(vp, STRcatalog)) { nlsclose(); nlsinit(); } #if defined(FILEC) && defined(TIOCSTI) else if (eq(vp, STRfilec)) filec = 1; #endif #endif /* NLS_CATALOGS */ }
static int binop(void) { const char *opnd1, *opnd2; struct t_op const *op; opnd1 = *t_wp; (void) t_lex(++t_wp); op = t_wp_op; if ((opnd2 = *++t_wp) == (char *)0) syntax(op->op_text, "argument expected"); switch (op->op_num) { default: #ifdef DEBUG abort(); /* NOTREACHED */ #endif case STREQ: return strcmp(opnd1, opnd2) == 0; case STRNE: return strcmp(opnd1, opnd2) != 0; case STRLT: return strcmp(opnd1, opnd2) < 0; case STRGT: return strcmp(opnd1, opnd2) > 0; case INTEQ: return getn(opnd1) == getn(opnd2); case INTNE: return getn(opnd1) != getn(opnd2); case INTGE: return getn(opnd1) >= getn(opnd2); case INTGT: return getn(opnd1) > getn(opnd2); case INTLE: return getn(opnd1) <= getn(opnd2); case INTLT: return getn(opnd1) < getn(opnd2); case FILNT: return newerf (opnd1, opnd2); case FILOT: return olderf (opnd1, opnd2); case FILEQ: return equalf (opnd1, opnd2); } }