/* * The trap builtin. */ int trapcmd(int argc __unused, char **argv) { char *action; int signo; int errors = 0; int i; while ((i = nextopt("l")) != '\0') { switch (i) { case 'l': printsignals(); return (0); } } argv = argptr; if (*argv == NULL) { for (signo = 0 ; signo < sys_nsig ; signo++) { if (signo < NSIG && trap[signo] != NULL) { out1str("trap -- "); out1qstr(trap[signo]); if (signo == 0) { out1str(" EXIT\n"); } else if (sys_signame[signo]) { out1fmt(" %s\n", sys_signame[signo]); } else { out1fmt(" %d\n", signo); } } } return 0; } action = NULL; if (*argv && sigstring_to_signum(*argv) == -1) { if (strcmp(*argv, "-") == 0) argv++; else { action = *argv; argv++; } } for (; *argv; argv++) { if ((signo = sigstring_to_signum(*argv)) == -1) { warning("bad signal %s", *argv); errors = 1; continue; } INTOFF; if (action) action = savestr(action); if (trap[signo]) ckfree(trap[signo]); trap[signo] = action; if (signo != 0) setsignal(signo); INTON; } return errors; }
int exportcmd(shinstance *psh, int argc, char **argv) { struct var *vp; char *name; const char *p; int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT; int pflag; pflag = nextopt(psh, "p") == 'p' ? 3 : 0; if (argc <= 1 || pflag) { showvars(psh, pflag ? argv[0] : 0, flag, pflag ); return 0; } while ((name = *psh->argptr++) != NULL) { if ((p = strchr(name, '=')) != NULL) { p++; } else { vp = find_var(psh, name, NULL, NULL); if (vp != NULL) { vp->flags |= flag; continue; } } setvar(psh, name, p, flag); } return 0; }
int fgcmd(int argc, char **argv) { struct job *jp; int i; int status; nextopt(""); jp = getjob(*argptr, 0); if (jp->jobctl == 0) error("job not created under job control"); out1fmt("%s", jp->ps[0].cmd); for (i = 1; i < jp->nprocs; i++) out1fmt(" | %s", jp->ps[i].cmd ); out1c('\n'); flushall(); for (i = 0; i < jp->nprocs; i++) if (tcsetpgrp(ttyfd, jp->ps[i].pid) != -1) break; if (i >= jp->nprocs) { error("Cannot set tty process group (%s) at %d", strerror(errno), __LINE__); } restartjob(jp); INTOFF; status = waitforjob(jp); INTON; return status; }
int unsetcmd(shinstance *psh, int argc, char **argv) { char **ap; int i; int flg_func = 0; int flg_var = 0; int ret = 0; while ((i = nextopt(psh, "evf")) != '\0') { if (i == 'f') flg_func = 1; else flg_var = i; } if (flg_func == 0 && flg_var == 0) flg_var = 1; for (ap = psh->argptr; *ap ; ap++) { if (flg_func) ret |= unsetfunc(psh, *ap); if (flg_var) ret |= unsetvar(psh, *ap, flg_var == 'e'); } return ret; }
int readcmd(int argc, char **argv) { char **ap; int backslash; char c; int rflag; char *prompt; char *p; int status; int i; rflag = 0; prompt = NULL; while ((i = nextopt("p:r")) != '\0') { if (i == 'p') prompt = optionarg; else rflag = 1; } if (prompt && isatty(0)) { out2str(prompt); #ifdef FLUSHERR flushall(); #endif } if (*(ap = argptr) == NULL) sh_error("arg count"); status = 0; backslash = 0; STARTSTACKSTR(p); for (;;) { if (read(0, &c, 1) != 1) { status = 1; break; } if (c == '\0') continue; if (backslash) { if (c == '\n') goto resetbs; STPUTC(CTLESC, p); goto put; } if (!rflag && c == '\\') { backslash++; continue; } if (c == '\n') break; put: STPUTC(c, p); resetbs: backslash = 0; } STACKSTRNUL(p); readcmd_handle_line(stackblock(), ap, p + 1 - (char *)stackblock()); return status; }
int waitcmd(int argc, char **argv) { struct job *job; int status, retval; struct job *jp; nextopt(""); if (!*argptr) { /* wait for all jobs */ jp = jobtab; if (jobs_invalid) return 0; for (;;) { if (jp >= jobtab + njobs) { /* no running procs */ return 0; } if (!jp->used || jp->state != JOBRUNNING) { jp++; continue; } if (dowait(WBLOCK, NULL) == -1) return 128 + SIGINT; jp = jobtab; } } retval = 127; /* XXXGCC: -Wuninitialized */ for (; *argptr; argptr++) { job = getjob(*argptr, 1); if (!job) { retval = 127; continue; } /* loop until process terminated or stopped */ while (job->state == JOBRUNNING) { if (dowait(WBLOCK|WNOFREE, job) == -1) return 128 + SIGINT; } status = job->ps[job->nprocs ? job->nprocs - 1 : 0].status; if (WIFEXITED(status)) retval = WEXITSTATUS(status); #if JOBS else if (WIFSTOPPED(status)) retval = WSTOPSIG(status) + 128; #endif else { /* XXX: limits number of signals */ retval = WTERMSIG(status) + 128; } if (!iflag) freejob(job); } return retval; }
int main(int argc, char *argv[]) { const char *modestr = NULL; const void *modep; mode_t fifomode; int ch, exitval; #ifdef SHELL while ((ch = nextopt("m:")) != '\0') #else while ((ch = getopt(argc, argv, "m:")) != -1) #endif switch(ch) { case 'm': f_mode = 1; #ifdef shell modestr = shoptarg; #else modestr = optarg; #endif break; case '?': default: usage(); } #ifdef SHELL argc -= argptr - argv; argv = argptr; #else argc -= optind; argv += optind; #endif if (argv[0] == NULL) usage(); if (f_mode) { umask(0); errno = 0; if ((modep = setmode(modestr)) == NULL) { if (errno) err(1, "%s", "setmode"); errx(1, "invalid file mode: %s", modestr); } fifomode = getmode(modep, BASEMODE); } else { fifomode = BASEMODE; } for (exitval = 0; *argv != NULL; ++argv) if (mkfifo(*argv, fifomode) < 0) { warn("%s", *argv); exitval = 1; } return(exitval); }
int trapcmd(int argc, char **argv) { char *action; char **ap; int signo; nextopt(nullstr); ap = argptr; if (!*ap) { for (signo = 0 ; signo < NSIG ; signo++) { if (trap[signo] != NULL) { out1fmt( "trap -- %s %s\n", single_quote(trap[signo]), signal_names[signo] ); } } return 0; } if (!ap[1]) action = NULL; else action = *ap++; while (*ap) { if ((signo = decode_signal(*ap, 0)) < 0) { outfmt(out2, "trap: %s: bad trap\n", *ap); return 1; } INTOFF; if (action) { if (action[0] == '-' && action[1] == '\0') action = NULL; else { if (*action) trapcnt++; action = savestr(action); } } if (trap[signo]) { if (*trap[signo]) trapcnt--; ckfree(trap[signo]); } trap[signo] = action; if (signo != 0) setsignal(signo); INTON; ap++; } return 0; }
int main(int argc, char *argv[], char *envp[]) { nextopt_t nopt = nextopt_INIT(argc, argv, "hV"); char opt; pid_t pid; progname = nextopt_progname(&nopt); while((opt = nextopt(&nopt))){ char optc[2] = {nopt.opt_got, '\0'}; switch(opt){ case 'h': usage(); die(0); break; case 'V': version(); die(0); break; case ':': fatal_usage("missing argument for option -", optc); break; case '?': if(nopt.opt_got != '?'){ fatal_usage("invalid option: -", optc); } /* else fallthrough: */ default : die_usage(); break; } } argc -= nopt.arg_ndx; argv += nopt.arg_ndx; if(argc < 1){ fatal_usage("missing required program argument"); } if((pid = fork()) == -1){ fatal_syserr("failure to detach"); } if(pid != 0){ /* parent exits: */ _exit(0); } setsid(); /* execvx() provides path search for prog */ execvx(argv[0], argv, envp, NULL); /* uh oh: */ fatal_syserr("unable to run ", argv[0]); /* not reached: */ return 0; }
int jobidcmd(int argc, char **argv) { struct job *jp; int i; nextopt(""); jp = getjob(*argptr, 0); for (i = 0 ; i < jp->nprocs ; ) { out1fmt("%ld", (long)jp->ps[i].pid); out1c(++i < jp->nprocs ? ' ' : '\n'); } return 0; }
int main(int argc, char *argv[], char *envp[]) { nextopt_t nopt = nextopt_INIT(argc, argv, "hV"); char opt; const char *prog = NULL; progname = nextopt_progname(&nopt); while((opt = nextopt(&nopt))){ char optc[2] = {nopt.opt_got, '\0'}; switch(opt){ case 'h': usage(); die(0); break; case 'V': version(); die(0); break; case ':': fatal_usage("missing argument for option -", optc); break; case '?': if(nopt.opt_got != '?'){ fatal_usage("invalid option: -", optc); } /* else fallthrough: */ default : die_usage(); break; } } argc -= nopt.arg_ndx; argv += nopt.arg_ndx; if(argc < 2){ fatal_usage("missing required argument(s)"); } /* our real executable: */ prog = argv[0]; /* ratchet alias into argv[0]: */ ++argv; /* execvx() provides path search for prog */ execvx(prog, argv, envp, NULL); /* uh oh: */ fatal_syserr("unable to run ", prog); /* not reached: */ return 0; }
int unaliascmd(int argc, char **argv) { int i; while ((i = nextopt("a")) != '\0') { if (i == 'a') { rmaliases(); return (0); } } for (i = 0; *argptr; argptr++) i = unalias(*argptr); return (i); }
int main(int argc, char *argv[]) { nextopt_t nopt = nextopt_INIT(argc, argv, "hV"); char opt; int i; progname = nextopt_progname(&nopt); while((opt = nextopt(&nopt))){ char optc[2] = {nopt.opt_got, '\0'}; switch(opt){ case 'V': version(); die(0); break; case 'h': usage(); die(0); break; case '?': if(nopt.opt_got != '?'){ eputs(progname, ": usage error: invalid option: -", optc); } /* fallthrough: */ default : die_usage(); break; } } argc -= nopt.arg_ndx; argv += nopt.arg_ndx; for(i = 0; resources[i] != NULL; ++i){ const char *resource = resources[i]; int r = rlimit_lookup(resource); char nfmt[NFMT_SIZE]; struct rlimit rlim; if(r == -1){ ioq_vputs(ioq1, resource, "\t[not provided on this platform]\n"); continue; } getrlimit(r, &rlim); ioq_vputs(ioq1, resource, "\t", rlimit_mesg(r), ": "); if(rlim.rlim_cur == RLIM_INFINITY){ ioq_vputs(ioq1, "unlimited\n"); } else { ioq_vputs(ioq1, nfmt_uint32(nfmt, rlim.rlim_cur), "\n"); } } ioq_flush(ioq1); return 0; }
int dotcmd(int argc, char **argv) { int status = 0; nextopt(nullstr); argv = argptr; if (*argv) { char *fullname; fullname = find_dot_file(*argv); setinputfile(fullname, INPUT_PUSH_FILE); commandname = fullname; status = cmdloop(0); popfile(); } return status; }
int unaliascmd(int argc, char **argv) { int i; while ((i = nextopt("a")) != '\0') { if (i == 'a') { rmaliases(); return (0); } } for (i = 0; *argptr; argptr++) { if (unalias(*argptr)) { outfmt(out2, "%s: %s not found\n", "unalias", *argptr); i = 1; } } return (i); }
int timescmd(int argc, char **argv) { struct tms tms; int u, s, cu, cs; char us[8], ss[8], cus[8], css[8]; nextopt(""); times(&tms); u = conv_time(tms.tms_utime, us, sizeof(us)); s = conv_time(tms.tms_stime, ss, sizeof(ss)); cu = conv_time(tms.tms_cutime, cus, sizeof(cus)); cs = conv_time(tms.tms_cstime, css, sizeof(css)); outfmt(out1, "%dm%ss %dm%ss\n%dm%ss %dm%ss\n", u, us, s, ss, cu, cus, cs, css); return 0; }
int bgcmd(int argc, char **argv) { struct job *jp; int i; nextopt(""); do { jp = getjob(*argptr, 0); if (jp->jobctl == 0) error("job not created under job control"); set_curjob(jp, 1); out1fmt("[%ld] %s", (long)(jp - jobtab + 1), jp->ps[0].cmd); for (i = 1; i < jp->nprocs; i++) out1fmt(" | %s", jp->ps[i].cmd ); out1c('\n'); flushall(); restartjob(jp); } while (*argptr && *++argptr); return 0; }
int timescmd(shinstance *psh, int argc, char **argv) { shtms tms; int u, s, cu, cs; char us[8], ss[8], cus[8], css[8]; nextopt(psh, ""); sh_times(psh, &tms); u = conv_time(tms.tms_utime, us, sizeof(us)); s = conv_time(tms.tms_stime, ss, sizeof(ss)); cu = conv_time(tms.tms_cutime, cus, sizeof(cus)); cs = conv_time(tms.tms_cstime, css, sizeof(css)); outfmt(psh->out1, "%dm%ss %dm%ss\n%dm%ss %dm%ss\n", u, us, s, ss, cu, cus, cs, css); return 0; }
int jobscmd(int argc, char **argv) { int mode, m; int sv = jobs_invalid; jobs_invalid = 0; mode = 0; while ((m = nextopt("lp"))) if (m == 'l') mode = SHOW_PID; else mode = SHOW_PGID; if (*argptr) do showjob(out1, getjob(*argptr,0), mode); while (*++argptr); else showjobs(out1, mode); jobs_invalid = sv; return 0; }
int main(int argc, char *argv[]) { nextopt_t nopt = nextopt_INIT(argc, argv, ":hVdL:S:x"); char opt; int opt_detach = 0; char *arg_sep = "::"; progname = nextopt_progname(&nopt); while((opt = nextopt(&nopt))){ char optc[2] = {nopt.opt_got, '\0'}; switch(opt){ case 'h': usage(); die(0); break; case 'V': version(); die(0); break; case 'd': opt_detach = 1; break; case 'L': /* label string ignored */ break; case 'S': arg_sep = nopt.opt_arg; break; case 'x': opt_super = 0; break; case ':': fatal_usage("missing argument for option -", optc); break; case '?': if(nopt.opt_got != '?'){ fatal_usage("invalid option: -", optc); } /* else fallthrough: */ default : die_usage(); break; } } argc -= nopt.arg_ndx; argv += nopt.arg_ndx; if(argc < 3){ fatal_usage("missing required arguments"); } deux_init(); /* proggy: */ deux[1].argv = argv; ++argv; while(argv){ if(cstr_cmp(*argv, arg_sep) == 0){ /* logger argv follows separator: */ deux[0].argv = &argv[1]; /* progger argv terminator: */ *argv = NULL; break; } ++argv; } if(deux[0].argv == NULL){ fatal_usage("missing required logger argument"); } if(opt_detach){ pid_t pid = fork(); switch(pid){ case -1: fatal_syserr("unable to detach"); break; case 0: /* child continues daemonized in new session: */ setsid(); break; default: /* parent exits: */ exit(0); } } /* initialize sigpipe[], etc: */ setup(); main_loop(); return 0; }
int ulimitcmd(int argc, char **argv) { int c; rlim_t val = 0; enum { SOFT = 0x1, HARD = 0x2 } how = SOFT | HARD; const struct limits *l; int set, all = 0; int optc, what; struct rlimit limit; what = 'f'; while ((optc = nextopt("HSabtfdsmcnpl")) != '\0') switch (optc) { case 'H': how = HARD; break; case 'S': how = SOFT; break; case 'a': all = 1; break; default: what = optc; } for (l = limits; l->name && l->option != what; l++) ; if (!l->name) error("internal error (%c)", what); set = *argptr ? 1 : 0; if (set) { char *p = *argptr; if (all || argptr[1]) error("too many arguments"); if (strcmp(p, "unlimited") == 0) val = RLIM_INFINITY; else { val = (rlim_t) 0; while ((c = *p++) >= '0' && c <= '9') { val = (val * 10) + (long)(c - '0'); if ((long)val < 0) break; } if (c) error("bad number"); val *= l->factor; } } if (all) { for (l = limits; l->name; l++) { getrlimit(l->cmd, &limit); if (how & SOFT) val = limit.rlim_cur; else if (how & HARD) val = limit.rlim_max; out1fmt("%-20s ", l->name); if (val == RLIM_INFINITY) out1fmt("unlimited\n"); else { val /= l->factor; #ifdef BSD4_4 out1fmt("%lld\n", (long long) val); #else out1fmt("%ld\n", (long) val); #endif } } return 0; } getrlimit(l->cmd, &limit); if (set) { if (how & HARD) limit.rlim_max = val; if (how & SOFT) limit.rlim_cur = val; if (setrlimit(l->cmd, &limit) < 0) error("error setting limit (%s)", strerror(errno)); } else { if (how & SOFT) val = limit.rlim_cur; else if (how & HARD) val = limit.rlim_max; if (val == RLIM_INFINITY) out1fmt("unlimited\n"); else { val /= l->factor; #ifdef BSD4_4 out1fmt("%lld\n", (long long) val); #else out1fmt("%ld\n", (long) val); #endif } } return 0; }
int readcmd(int argc, char **argv) { char **ap; char c; int rflag; char *prompt; const char *ifs; char *p; int startword; int status; int i; int is_ifs; int saveall = 0; rflag = 0; prompt = NULL; while ((i = nextopt("p:r")) != '\0') { if (i == 'p') prompt = optionarg; else rflag = 1; } if (prompt && isatty(0)) { out2str(prompt); flushall(); } if (*(ap = argptr) == NULL) error("arg count"); if ((ifs = bltinlookup("IFS", 1)) == NULL) ifs = " \t\n"; status = 0; startword = 2; STARTSTACKSTR(p); for (;;) { if (read(0, &c, 1) != 1) { status = 1; break; } if (c == '\0') continue; if (c == '\\' && !rflag) { if (read(0, &c, 1) != 1) { status = 1; break; } if (c != '\n') STPUTC(c, p); continue; } if (c == '\n') break; if (strchr(ifs, c)) is_ifs = strchr(" \t\n", c) ? 1 : 2; else is_ifs = 0; if (startword != 0) { if (is_ifs == 1) { /* Ignore leading IFS whitespace */ if (saveall) STPUTC(c, p); continue; } if (is_ifs == 2 && startword == 1) { /* Only one non-whitespace IFS per word */ startword = 2; if (saveall) STPUTC(c, p); continue; } } if (is_ifs == 0) { /* append this character to the current variable */ startword = 0; if (saveall) /* Not just a spare terminator */ saveall++; STPUTC(c, p); continue; } /* end of variable... */ startword = is_ifs; if (ap[1] == NULL) { /* Last variable needs all IFS chars */ saveall++; STPUTC(c, p); continue; } STACKSTRNUL(p); setvar(*ap, stackblock(), 0); ap++; STARTSTACKSTR(p); } STACKSTRNUL(p); /* Remove trailing IFS chars */ for (; stackblock() <= --p; *p = 0) { if (!strchr(ifs, *p)) break; if (strchr(" \t\n", *p)) /* Always remove whitespace */ continue; if (saveall > 1) /* Don't remove non-whitespace unless it was naked */ break; } setvar(*ap, stackblock(), 0); /* Set any remaining args to "" */ while (*++ap != NULL) setvar(*ap, nullstr, 0); return status; }
int ulimitcmd(int argc, char **argv) { int c; rlim_t val = 0; enum limtype how = SOFT | HARD; const struct limits *l; int set, all = 0; int optc, what; struct rlimit limit; what = 'f'; while ((optc = nextopt("HSa" #ifdef RLIMIT_CPU "t" #endif #ifdef RLIMIT_FSIZE "f" #endif #ifdef RLIMIT_DATA "d" #endif #ifdef RLIMIT_STACK "s" #endif #ifdef RLIMIT_CORE "c" #endif #ifdef RLIMIT_RSS "m" #endif #ifdef RLIMIT_MEMLOCK "l" #endif #ifdef RLIMIT_NPROC "p" #endif #ifdef RLIMIT_NOFILE "n" #endif #ifdef RLIMIT_AS "v" #endif #ifdef RLIMIT_LOCKS "w" #endif )) != '\0') switch (optc) { case 'H': how = HARD; break; case 'S': how = SOFT; break; case 'a': all = 1; break; default: what = optc; } for (l = limits; l->option != what; l++) ; set = *argptr ? 1 : 0; if (set) { char *p = *argptr; if (all || argptr[1]) sh_error("too many arguments"); if (strcmp(p, "unlimited") == 0) val = RLIM_INFINITY; else { val = (rlim_t) 0; while ((c = *p++) >= '0' && c <= '9') { val = (val * 10) + (long)(c - '0'); if (val < (rlim_t) 0) break; } if (c) sh_error("bad number"); val *= l->factor; } } if (all) { for (l = limits; l->name; l++) { getrlimit(l->cmd, &limit); out1fmt("%-20s ", l->name); printlim(how, &limit, l); } return 0; } getrlimit(l->cmd, &limit); if (set) { if (how & HARD) limit.rlim_max = val; if (how & SOFT) limit.rlim_cur = val; if (setrlimit(l->cmd, &limit) < 0) sh_error("error setting limit (%s)", strerror(errno)); } else { printlim(how, &limit, l); } return 0; }
int umaskcmd(int argc, char **argv) { char *ap; int mask; int i; int symbolic_mode = 0; while ((i = nextopt("S")) != '\0') { symbolic_mode = 1; } INTOFF; mask = umask(0); umask(mask); INTON; if ((ap = *argptr) == NULL) { if (symbolic_mode) { char buf[18]; int j; mask = ~mask; ap = buf; for (i = 0; i < 3; i++) { *ap++ = "ugo"[i]; *ap++ = '='; for (j = 0; j < 3; j++) if (mask & (1 << (8 - (3*i + j)))) *ap++ = "rwx"[j]; *ap++ = ','; } ap[-1] = '\0'; out1fmt("%s\n", buf); } else { out1fmt("%.4o\n", mask); } } else { int new_mask; if (isdigit((unsigned char) *ap)) { new_mask = 0; do { if (*ap >= '8' || *ap < '0') sh_error(illnum, *argptr); new_mask = (new_mask << 3) + (*ap - '0'); } while (*++ap != '\0'); } else { int positions, new_val; char op; mask = ~mask; new_mask = mask; positions = 0; while (*ap) { while (*ap && strchr("augo", *ap)) switch (*ap++) { case 'a': positions |= 0111; break; case 'u': positions |= 0100; break; case 'g': positions |= 0010; break; case 'o': positions |= 0001; break; } if (!positions) positions = 0111; /* default is a */ if (!strchr("=+-", op = *ap)) break; ap++; new_val = 0; while (*ap && strchr("rwxugoXs", *ap)) switch (*ap++) { case 'r': new_val |= 04; break; case 'w': new_val |= 02; break; case 'x': new_val |= 01; break; case 'u': new_val |= mask >> 6; break; case 'g': new_val |= mask >> 3; break; case 'o': new_val |= mask >> 0; break; case 'X': if (mask & 0111) new_val |= 01; break; case 's': /* ignored */ break; } new_val = (new_val & 07) * positions; switch (op) { case '-': new_mask &= ~new_val; break; case '=': new_mask = new_val | (new_mask & ~(positions * 07)); break; case '+': new_mask |= new_val; } if (*ap == ',') { positions = 0; ap++; } else if (!strchr("=+-", *ap)) break; } if (*ap) { sh_error("Illegal mode: %s", *argptr); return 1; } new_mask = ~new_mask; } umask(new_mask); } return 0; }
int readcmd(int argc, char **argv) { char **ap; char c; int rflag; char *prompt; char *p; int startloc; int newloc; int status; int i; rflag = 0; prompt = NULL; while ((i = nextopt("p:r")) != '\0') { if (i == 'p') prompt = optionarg; else rflag = 1; } if (prompt && isatty(0)) { out2str(prompt); #ifdef FLUSHERR flushall(); #endif } if (*(ap = argptr) == NULL) sh_error("arg count"); status = 0; STARTSTACKSTR(p); goto start; for (;;) { switch (read(0, &c, 1)) { case 1: break; default: if (errno == EINTR && !pendingsigs) continue; /* fall through */ case 0: status = 1; goto out; } if (c == '\0') continue; if (newloc >= startloc) { if (c == '\n') goto resetbs; goto put; } if (!rflag && c == '\\') { newloc = p - (char *)stackblock(); continue; } if (c == '\n') break; put: CHECKSTRSPACE(2, p); if (strchr(qchars, c)) USTPUTC(CTLESC, p); USTPUTC(c, p); if (newloc >= startloc) { resetbs: recordregion(startloc, newloc, 0); start: startloc = p - (char *)stackblock(); newloc = startloc - 1; } } out: recordregion(startloc, p - (char *)stackblock(), 0); STACKSTRNUL(p); readcmd_handle_line(p + 1, ap); return status; }
int32_t printfcmd(int32_t argc, cstring_t argv[]) { size_t len; int32_t chopped, end, rval; cstring_t format; cstring_t fmt; cstring_t start; nextopt(""); argc -= (int32_t)(intptr_t)(argptr - argv); argv = argptr; if (argc < 1) { usage(); return (1); } INTOFF; /* * Basic algorithm is to scan the format string for conversion * specifications -- once one is found, find out if the field * width or precision is a '*'; if it is, gather up value. Note, * format strings are reused as necessary to use up the provided * arguments, arguments of zero/null string are provided to use * up the format string. */ fmt = format = *argv; chopped = escape(fmt, 1, &len); /* backslash interpretation */ rval = end = 0; gargv = ++argv; for (;;) { start = fmt; while (fmt < format + len) { if (fmt[0] == '%') { fwrite(start, 1, fmt - start, stdout); if (fmt[1] == '%') { /* %% prints a % */ putchar('%'); fmt += 2; } else { fmt = printf_doformat(fmt, &rval); if (fmt == NULL) { INTON; return (1); } end = 0; } start = fmt; } else fmt++; } if (end == 1) { warnx("missing format character"); INTON; return (1); } fwrite(start, 1, fmt - start, stdout); if (chopped || !*gargv) { INTON; return (rval); } /* Restart at the beginning of the format string. */ fmt = format; end = 1; } /* NOTREACHED */ }
int printfcmd(int argc, char *argv[]) { char *fmt; char *format; int ch; rval = 0; nextopt(nullstr); argv = argptr; format = *argv; if (!format) { warnx("usage: printf format [arg ...]"); goto err; } gargv = ++argv; #define SKIP1 "#-+ 0" #define SKIP2 "*0123456789" do { /* * Basic algorithm is to scan the format string for conversion * specifications -- once one is found, find out if the field * width or precision is a '*'; if it is, gather up value. * Note, format strings are reused as necessary to use up the * provided arguments, arguments of zero/null string are * provided to use up the format string. */ /* find next format specification */ for (fmt = format; (ch = *fmt++) ;) { char *start; char nextch; int array[2]; int *param; if (ch == '\\') { int c_ch; fmt = conv_escape(fmt, &c_ch); ch = c_ch; goto pc; } if (ch != '%' || (*fmt == '%' && (++fmt || 1))) { pc: blt_putchar(ch); continue; } /* Ok - we've found a format specification, Save its address for a later blt_printf(). */ start = fmt - 1; param = array; /* skip to field width */ fmt += strspn(fmt, SKIP1); if (*fmt == '*') *param++ = getintmax(); /* skip to possible '.', get following precision */ fmt += strspn(fmt, SKIP2); if (*fmt == '.') ++fmt; if (*fmt == '*') *param++ = getintmax(); fmt += strspn(fmt, SKIP2); ch = *fmt; if (!ch) { warnx("missing format character"); goto err; } /* null terminate format string to we can use it as an argument to printf. */ nextch = fmt[1]; fmt[1] = 0; switch (ch) { case 'b': { int done = conv_escape_str(getstr()); char *p = stackblock(); *fmt = 's'; PF(start, p); /* escape if a \c was encountered */ if (done) goto out; *fmt = 'b'; break; } case 'c': { int p = getchr(); PF(start, p); break; } case 's': { char *p = getstr(); PF(start, p); break; } case 'd': case 'i': { intmax_t p = getintmax(); char *f = mklong(start, fmt); PF(f, p); break; } case 'o': case 'u': case 'x': case 'X': { uintmax_t p = getuintmax(); char *f = mklong(start, fmt); PF(f, p); break; } case 'e': case 'E': case 'f': case 'g': case 'G': { double p = getdouble(); PF(start, p); break; } default: warnx("%s: invalid directive", start); goto err; } *++fmt = nextch; } } while (gargv != argv && *gargv); out: return rval; err: return 1; }
int umaskcmd(int argc, char **argv) { char *ap; int mask; int i; int symbolic_mode = 0; while ((i = nextopt("S")) != '\0') { symbolic_mode = 1; } INTOFF; mask = umask(0); umask(mask); INTON; if ((ap = *argptr) == NULL) { if (symbolic_mode) { char u[4], g[4], o[4]; i = 0; if ((mask & S_IRUSR) == 0) u[i++] = 'r'; if ((mask & S_IWUSR) == 0) u[i++] = 'w'; if ((mask & S_IXUSR) == 0) u[i++] = 'x'; u[i] = '\0'; i = 0; if ((mask & S_IRGRP) == 0) g[i++] = 'r'; if ((mask & S_IWGRP) == 0) g[i++] = 'w'; if ((mask & S_IXGRP) == 0) g[i++] = 'x'; g[i] = '\0'; i = 0; if ((mask & S_IROTH) == 0) o[i++] = 'r'; if ((mask & S_IWOTH) == 0) o[i++] = 'w'; if ((mask & S_IXOTH) == 0) o[i++] = 'x'; o[i] = '\0'; out1fmt("u=%s,g=%s,o=%s\n", u, g, o); } else { out1fmt("%.4o\n", mask); } } else { if (isdigit((unsigned char)*ap)) { mask = 0; do { if (*ap >= '8' || *ap < '0') error("Illegal number: %s", argv[1]); mask = (mask << 3) + (*ap - '0'); } while (*++ap != '\0'); umask(mask); } else error("Illegal mode: %s", ap); } return 0; }
int main(int argc, char *argv[], char *envp[]) { nextopt_t nopt = nextopt_INIT(argc, argv, ":hVb:ek:p:s:v"); char opt; const char *prog = NULL; uint32_t pid = 0; const char *z; size_t n; progname = nextopt_progname(&nopt); while((opt = nextopt(&nopt))){ char optc[2] = {nopt.opt_got, '\0'}; switch(opt){ case 'V': version(); die(0); break; case 'h': usage(); die(0); break; case 'b': arg_base = nopt.opt_arg; break; case 'e': ++opt_e; break; case 'k': arg_key = nopt.opt_arg; break; case 'p': z = nuscan_uint32(&pid, nopt.opt_arg); if(*z != '\0'){ fatal_usage("bad numeric argument for -", optc, ": ", nopt.opt_arg); } break; case 's': arg_set = nopt.opt_arg; break; case 'v': ++opt_v; break; case ':': fatal_usage("missing argument for option -", optc); break; case '?': if(nopt.opt_got != '?'){ fatal_usage("invalid option: -", optc); } /* else fallthrough: */ default : die_usage(); break; } } argc -= nopt.arg_ndx; argv += nopt.arg_ndx; if(argc > 0) prog = argv[0]; if(prog == NULL){ fatal_usage("missing required program argument"); } if(arg_base == NULL) arg_base = getenv("CHOOM_BASE"); if(arg_base == NULL) arg_base = CHOOM_BASE_DEFAULT; if(arg_base[0] != '/'){ fatal_usage("path base is not absolute (must begin with `/'): ", arg_base); } if(arg_key == NULL) arg_key = getenv("CHOOM_KEY"); if(arg_key == NULL) arg_key = CHOOM_KEY_DEFAULT; if(arg_set == NULL) arg_set = getenv("CHOOM_SET"); if(arg_set == NULL) arg_set = CHOOM_SET_DEFAULT; nfmt_uint32(pidfmt, (pid == 0) ? (uint32_t)getpid() : pid); n = cstr_vlen(arg_base, "/", pidfmt, "/", arg_key); if((sizeof pathbuf) - n < 5){ errno = ENAMETOOLONG; fatal_syserr("path too long: ", arg_base, "/", pidfmt, "/", arg_key); } cstr_vcopy(pathbuf, arg_base, "/", pidfmt, "/", arg_key); n = cstr_vlen(arg_set, "\n"); if((sizeof setbuf) - n < 1){ fatal_usage("setting too long: ", arg_set); } cstr_vcopy(setbuf, arg_set, "\n"); do_choom(); execvx(prog, argv, envp, NULL); fatal_syserr("unable to run ", prog); /* not reached: */ return 0; }
int main(int argc, char *argv[], char *envp[]) { nextopt_t nopt = nextopt_INIT(argc, argv, ":hVL:"); char opt; uint32_t secs; const char *z; progname = nextopt_progname(&nopt); while((opt = nextopt(&nopt))){ char optc[2] = {nopt.opt_got, '\0'}; switch(opt){ case 'h': usage(); die(0); break; case 'V': version(); die(0); break; case 'L': /* label string ignored */ break; case ':': fatal_usage("missing argument for option -", optc); break; case '?': if(nopt.opt_got != '?'){ fatal_usage("invalid option: -", optc); } /* else fallthrough: */ default : die_usage(); break; } } argc -= nopt.arg_ndx; argv += nopt.arg_ndx; if(argc < 2){ fatal_usage("missing required argument(s)"); } z = nuscan_uint32(&secs, argv[0]); if(*z != '\0'){ fatal_usage("bad numeric argument for secs: ", argv[0]); } ++argv; /* catch SIGALRM on pause()/sleep() without termination: */ sig_catch(SIGALRM, sig_trap); if(secs == 0) pause(); else sleep(secs); sig_uncatch(SIGALRM); errno = 0; /* execvx() provides path search for prog */ execvx(argv[0], argv, envp, NULL); /* uh oh: */ fatal_syserr("unable to run ", argv[0]); /* not reached: */ return 0; }