static void test_multiply_dollar_5x3x3() { Expression *five = dollar( 5 ); Expression *product = multiply( multiply( five, 3 ), 3 ); Expression *fortyfive = dollar( 45 ); assert_true( equal( reduce( product, USD ), money_from( fortyfive ) ) ); free( five ); free( product ); free( fortyfive ); }
static void test_multiply_dollar_5x3() { Money *five = dollar( 5 ); Money *product = multiply( five, 3 ); Money *fifteen = dollar( 15 ); assert_true( equal( product, fifteen ) ); free( five ); free( product ); free( fifteen ); }
static void test_multiply_dollar_5x2() { Expression *five = dollar( 5 ); Expression *product = multiply( five, 2 ); Expression *ten = dollar( 10 ); assert_true( equal( reduce( product, USD ), money_from( ten ) ) ); free( five ); free( product ); free( ten ); }
static void test_multiply_dollar_5x2() { Money *five = dollar( 5 ); Money *product = multiply( five, 2 ); Money *ten = dollar( 10 ); assert_true( equal( product, ten ) ); free( five ); free( product ); free( ten ); }
static void test_plus_returns_sum() { Expression *five = dollar( 5 ); Expression *addend_five = dollar( 5 ); Expression *result = plus( five, addend_five ); Sum *sum = ( Sum * ) result->value; assert_true( equal( money_from( five ), money_from( sum->augend ) ) ); assert_true( equal( money_from( addend_five ), money_from( sum->addend ) ) ); free_expression( five ); free_expression( addend_five ); free_expression( result ); delete_all_rates(); }
static void test_multiply_dollar_5x2() { Expression *five = dollar( 5 ); Expression *product = multiply( five, 2 ); Expression *ten = dollar( 10 ); Money *reduced = reduce( product, USD ); assert_true( equal( reduced, money_from( ten ) ) ); free_expression( five ); free_expression( product ); free_expression( ten ); free_money( reduced ); delete_all_rates(); }
static void test_simple_addition() { Expression *five = dollar( 5 ); Expression *addend_five = dollar( 5 ); Expression *ten = dollar( 10 ); Expression *sum = plus( five, addend_five ); Money *reduced = reduce( sum, USD ); assert_true( equal( money_from( ten ), reduced ) ); free( five ); free( addend_five ); free( sum ); free( reduced ); free( ten ); }
static void test_equal() { Money *five_dollar1 = money_from( dollar( 5 ) ); Money *five_dollar2 = money_from( dollar( 5 ) ); Money *six_dollar = money_from( dollar( 6 ) ); Money *five_franc = money_from( franc( 5 ) ); assert_true( equal( five_dollar1, five_dollar2 ) ); assert_false( equal( five_dollar1, six_dollar ) ); assert_false( equal( five_dollar1, five_franc ) ); free( five_dollar1 ); free( five_dollar2 ); free( six_dollar ); free( five_franc ); }
template <typename Container> inline std::size_t find_replaces(std::string const &value, Container &cont) { std::size_t max = 0; cont.clear(); is_equal<char> dollar('$'); is_numeric<char> numeric_matcher; std::string::const_iterator i = value.begin(), begin = value.begin(), end = value.end(); while (i != end) { i = next_matched(i, end, dollar); if (i == end) { break; } std::string::const_iterator pos = next_not_matched(i + 1, end, numeric_matcher); if (std::distance(i, pos) > 1) { regex_data data = { i - begin, pos - begin, scan_integer<std::size_t>(i + 1, pos) }; cont.push_back(data); std::string tmp(value.substr(i + 1 - begin, pos - i - 1)); std::size_t s = atoi(tmp.c_str()); max = std::max(max, s); } i = pos; } return max; }
//PROGRAMA PRINCIPAL CD void ChangeDirectory(Comando* comando){ char* path; int error; char buf[1024]; char dir[1024]; if(comando->arg[1]!=NULL){ if(dollar(comando->arg[1][0])){ path=ConvertDollarVar(comando->arg[1]); if(path!=NULL){ fprintf(stderr, "Error: cant change directory %s\n", path); } } if(comando->arg[1][0]!='/'){ getcwd(buf, sizeof(buf)); sprintf(dir, "%s/%s", buf, comando->arg[1]); error=change_directory(dir); if(error){ fprintf(stderr, "Error: cant change directory %s\n", dir); } }else{ error=change_directory(comando->arg[1]); if(error){ fprintf(stderr, "Error: cant change directory %s\n", dir); } } }else{ path=getEnv("HOME"); error=change_directory(path); if(error){ fprintf(stderr, "Error: cant change directory %s\n", path); } } }
int check_cmd(t_shell *sh, t_node *tree) { int i; i = -1; number_reset(sh); sh->cmd = my_str_to_wordtab(tree->str); dollar(sh); check_point_slash(sh, sh->env); if (built_in(sh) == -1) return (-1); while (sh->path != NULL && sh->path[++i] != NULL && sh->ch == 0) if (access(strcat(sh->path[i], sh->cmd[0]), X_OK) == 0) exec_cmd(sh->path[i], sh->cmd, sh->env, sh); if (sh->ch == 0) exec_slah_bin(sh->cmd, sh); if (sh->ch == 0) { fprintf(stderr, "Error: '%s' command not found\n", sh->cmd[0]); sh->ok_cmd = -1; return (0); } my_free(sh->cmd); return (0); }
static void test_reduce_sum() { Expression *three_usd = dollar( 3 ); Expression *four_usd = dollar( 4 ); Expression *seven_usd = dollar( 7 ); Expression *exp = plus( three_usd, four_usd ); Money *result = reduce( exp , USD ); assert_true( equal( result , money_from( seven_usd ) ) ); free_expression( three_usd ); free_expression( four_usd ); free_expression( seven_usd ); free_expression( exp ); free_money( result ); delete_all_rates(); }
static void test_multiply_dollar_5x3x3() { Expression *five = dollar( 5 ); Expression *product1 = multiply( five, 3 ); Expression *product2 = multiply( product1, 3 ); Expression *fortyfive = dollar( 45 ); Money *reduced = reduce( product2, USD ); assert_true( equal( reduced, money_from( fortyfive ) ) ); free_expression( five ); free_expression( product1 ); free_expression( product2 ); free_expression( fortyfive ); free_money( reduced ); delete_all_rates(); }
static void test_equal() { Expression *five_dollar1 = dollar( 5 ); Expression *five_dollar2 = dollar( 5 ); Expression *six_dollar = dollar( 6 ); Expression *five_franc = franc( 5 ); assert_true( equal( money_from( five_dollar1 ), money_from( five_dollar2 ) ) ); assert_false( equal( money_from( five_dollar1 ), money_from( six_dollar ) ) ); assert_false( equal( money_from( five_dollar1 ), money_from( five_franc ) ) ); free_expression( five_dollar1 ); free_expression( five_dollar2 ); free_expression( six_dollar ); free_expression( five_franc ); delete_all_rates(); }
static void test_mixed_addition() { Expression *five_bucks = dollar( 5 ); Expression *ten_francs = franc( 10 ); Expression *ten_usd = dollar( 10 ); add_rate( CHF, USD, 2 ); Expression *exp = plus( five_bucks, ten_francs ); Money *result = reduce( exp, USD ); assert_true( equal( money_from( ten_usd ), result ) ); free_expression( five_bucks ); free_expression( ten_francs ); free_expression( ten_usd ); free_expression( exp ); free_money( result ); delete_all_rates(); }
static void test_multiple_addition() { Expression *five_bucks = dollar( 5 ); Expression *ten_francs = franc( 10 ); Expression *fifteen_bucks = dollar( 15 ); add_rate( CHF, USD, 2 ); Expression *exp1 = plus( five_bucks, ten_francs ); Expression *exp2 = plus( exp1, five_bucks ); Money *result = reduce( exp2, USD ); assert_true( equal( money_from( fifteen_bucks ), result ) ); free_expression( five_bucks ); free_expression( ten_francs ); free_expression( fifteen_bucks ); free_expression( exp1 ); free_expression( exp2 ); free_money( result ); delete_all_rates(); }
static void test_reduce_different_currency() { Expression *two_franc = franc( 2 ); Expression *one_dollar = dollar( 1 ); add_rate( CHF, USD, 2 ); Money *result = reduce( two_franc, USD ); assert_true( equal( result, money_from( one_dollar ) ) ); free_expression( two_franc ); free_expression( one_dollar ); free_money( result ); delete_all_rates(); }
/* expand one blank-terminated string, processing quotes and $ signs */ char* expand(Exec *e, char *s, char **ends) { char *p, *ep, *val; int namelen, quoting; p = ebuf; ep = ebuf+sizeof ebuf-1; quoting = 0; while(p<ep && *s!='\0' && (quoting || (*s!=' ' && *s!='\t'))){ if(*s == '\''){ s++; if(!quoting) quoting = 1; else if(*s == '\''){ *p++ = '\''; s++; }else quoting = 0; continue; } if(quoting || *s!='$'){ *p++ = *s++; continue; } s++; val = dollar(e, s, &namelen); if(val == nil){ *p++ = '$'; continue; } if(ep-p < strlen(val)) return "string-too-long"; strcpy(p, val); p += strlen(val); s += namelen; } if(ends) *ends = s; *p = '\0'; /* disabled due to default plumbing having broken rule */ if(0 && quoting) return "eof-in-quoted-string"; return ebuf; }
static void test_currency() { assert_int_equal( USD, currency_of( dollar( 1 ) ) ); assert_int_equal( CHF, currency_of( franc( 1 ) ) ); }
void cmd(void) { char *p, *a, *cp, *gotint; char addr[128]; static char *cmdlet = ":$?/=>"; int n, i; notify(catcher); dot = reg.pc; setjmp(errjmp); for(;;) { Bflush(bioout); p = buf; n = 0; for(;;) { i = Bgetc(bin); if(i < 0) exits(0); *p++ = i; n++; if(i == '\n') break; } if(buf[0] == '\n') strcpy(buf, lastcmd); else { buf[n-1] = '\0'; strcpy(lastcmd, buf); } p = buf; a = addr; for(;;) { p = nextc(p); if(*p == 0 || strchr(cmdlet, *p)) break; *a++ = *p++; } *a = '\0'; cmdcount = 1; cp = strchr(addr, ','); if(cp != 0) { if(cp[1] == '#') cmdcount = strtoul(cp+2, &gotint, 16); else cmdcount = strtoul(cp+1, &gotint, 0); *cp = '\0'; } switch(*p) { case '$': dollar(p+1); break; case ':': colon(addr, p+1); break; case '/': case '?': dot = expr(addr); for(i = 0; i < cmdcount; i++) quesie(p+1); break; case '=': eval(addr, p+1); break; case '>': setreg(addr, p+1); break; default: Bprint(bioout, "?\n"); break; } } }
/*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(); }