📄 c_ksh.c
字号:
ap = tenter(t, alias, h); ap->type = tflag ? CTALIAS : CALIAS; /* Are we setting the value or just some flags? */ if ((val && !tflag) || (!val && tflag && !Uflag)) { if (ap->flag&ALLOC) { ap->flag &= ~(ALLOC|ISSET); afree((void*)ap->val.s, APERM); } /* ignore values for -t (at&t ksh does this) */ newval = tflag ? search(alias, path, X_OK, (int *) 0) : val; if (newval) { ap->val.s = str_save(newval, APERM); ap->flag |= ALLOC|ISSET; } else ap->flag &= ~ISSET; } ap->flag |= DEFINED; if (prefix == '+') ap->flag &= ~xflag; else ap->flag |= xflag; if (val) afree(alias, ATEMP); } return rv;}intc_unalias(wp) char **wp;{ register struct table *t = &aliases; register struct tbl *ap; int rv = 0, all = 0; int optc; while ((optc = ksh_getopt(wp, &builtin_opt, "adt")) != EOF) switch (optc) { case 'a': all = 1; break; case 'd': t = &homedirs; break; case 't': t = &taliases; break; case '?': return 1; } wp += builtin_opt.optind; for (; *wp != NULL; wp++) { ap = tsearch(t, *wp, hash(*wp)); if (ap == NULL) { rv = 1; /* POSIX */ continue; } if (ap->flag&ALLOC) { ap->flag &= ~(ALLOC|ISSET); afree((void*)ap->val.s, APERM); } ap->flag &= ~(DEFINED|ISSET|EXPORT); } if (all) { struct tstate ts; for (twalk(&ts, t); (ap = tnext(&ts)); ) { if (ap->flag&ALLOC) { ap->flag &= ~(ALLOC|ISSET); afree((void*)ap->val.s, APERM); } ap->flag &= ~(DEFINED|ISSET|EXPORT); } } return rv;}#ifdef KSHintc_let(wp) char **wp;{ int rv = 1; long val; if (wp[1] == (char *) 0) /* at&t ksh does this */ bi_errorf("no arguments"); else for (wp++; *wp; wp++) if (!evaluate(*wp, &val, KSH_RETURN_ERROR)) { rv = 2; /* distinguish error from zero result */ break; } else rv = val == 0; return rv;}#endif /* KSH */intc_jobs(wp) char **wp;{ int optc; int flag = 0; int nflag = 0; int rv = 0; while ((optc = ksh_getopt(wp, &builtin_opt, "lpnz")) != EOF) switch (optc) { case 'l': flag = 1; break; case 'p': flag = 2; break; case 'n': nflag = 1; break; case 'z': /* debugging: print zombies */ nflag = -1; break; case '?': return 1; } wp += builtin_opt.optind; if (!*wp) if (j_jobs((char *) 0, flag, nflag)) rv = 1; else for (; *wp; wp++) if (j_jobs(*wp, flag, nflag)) rv = 1; return rv;}#ifdef JOBSintc_fgbg(wp) char **wp;{ int bg = strcmp(*wp, "bg") == 0; int UNINITIALIZED(rv); if (!Flag(FMONITOR)) { bi_errorf("job control not enabled"); return 1; } if (ksh_getopt(wp, &builtin_opt, null) == '?') return 1; wp += builtin_opt.optind; if (*wp) for (; *wp; wp++) rv = j_resume(*wp, bg); else rv = j_resume("%%", bg); /* POSIX says fg shall return 0 (unless an error occurs). * at&t ksh returns the exit value of the job... */ return (bg || Flag(FPOSIX)) ? 0 : rv;}#endifstruct kill_info { int num_width; int name_width;};static char *kill_fmt_entry ARGS((void *arg, int i, char *buf, int buflen));/* format a single kill item */static char *kill_fmt_entry(arg, i, buf, buflen) void *arg; int i; char *buf; int buflen;{ struct kill_info *ki = (struct kill_info *) arg; i++; if (sigtraps[i].name) shf_snprintf(buf, buflen, "%*d %*s %s", ki->num_width, i, ki->name_width, sigtraps[i].name, sigtraps[i].mess); else shf_snprintf(buf, buflen, "%*d %*d %s", ki->num_width, i, ki->name_width, sigtraps[i].signal, sigtraps[i].mess); return buf;}intc_kill(wp) char **wp;{ Trap *t = (Trap *) 0; char *p; int lflag = 0; int i, n, rv, sig; /* assume old style options if -digits or -UPPERCASE */ if ((p = wp[1]) && *p == '-' && (digit(p[1]) || isupper(p[1]))) { if (!(t = gettrap(p + 1, TRUE))) { bi_errorf("bad signal `%s'", p + 1); return 1; } i = (wp[2] && strcmp(wp[2], "--") == 0) ? 3 : 2; } else { int optc; while ((optc = ksh_getopt(wp, &builtin_opt, "ls:")) != EOF) switch (optc) { case 'l': lflag = 1; break; case 's': if (!(t = gettrap(builtin_opt.optarg, TRUE))) { bi_errorf("bad signal `%s'", builtin_opt.optarg); return 1; } case '?': return 1; } i = builtin_opt.optind; } if ((lflag && t) || (!wp[i] && !lflag)) { shf_fprintf(shl_out,"Usage: kill [ -s signame | -signum | -signame ] {pid|job}...\n\ kill -l [exit_status]\n" ); bi_errorf(null); return 1; } if (lflag) { if (wp[i]) { for (; wp[i]; i++) { if (!bi_getn(wp[i], &n)) return 1; if (n > 128 && n < 128 + SIGNALS) n -= 128; if (n > 0 && n < SIGNALS && sigtraps[n].name) shprintf("%s\n", sigtraps[n].name); else shprintf("%d\n", n); } } else if (Flag(FPOSIX)) { p = null; for (i = 1; i < SIGNALS; i++, p = space) if (sigtraps[i].name) shprintf("%s%s", p, sigtraps[i].name); shprintf(newline); } else { int w, i; int mess_width; struct kill_info ki; for (i = SIGNALS, ki.num_width = 1; i >= 10; i /= 10) ki.num_width++; ki.name_width = mess_width = 0; for (i = 0; i < SIGNALS; i++) { w = sigtraps[i].name ? strlen(sigtraps[i].name) : ki.num_width; if (w > ki.name_width) ki.name_width = w; w = strlen(sigtraps[i].mess); if (w > mess_width) mess_width = w; } print_columns(shl_stdout, SIGNALS - 1, kill_fmt_entry, (void *) &ki, ki.num_width + ki.name_width + mess_width + 3); } return 0; } rv = 0; sig = t ? t->signal : SIGTERM; for (; (p = wp[i]); i++) { if (*p == '%') { if (j_kill(p, sig)) rv = 1; } else if (!getn(p, &n)) { bi_errorf("%s: arguments must be jobs or process ids", p); rv = 1; } else { /* use killpg if < -1 since -1 does special things for * some non-killpg-endowed kills */ if ((n < -1 ? killpg(-n, sig) : kill(n, sig)) < 0) { bi_errorf("%s: %s", p, strerror(errno)); rv = 1; } } } return rv;}voidgetopts_reset(val) int val;{ if (val >= 1) { ksh_getopt_reset(&user_opt, GF_NONAME | (Flag(FPOSIX) ? 0 : GF_PLUSOPT)); user_opt.optind = user_opt.uoptind = val; }}intc_getopts(wp) char **wp;{ int argc; const char *options; const char *var; int optc; int ret; char buf[3]; struct tbl *vq, *voptarg; if (ksh_getopt(wp, &builtin_opt, null) == '?') return 1; wp += builtin_opt.optind; options = *wp++; if (!options) { bi_errorf("missing options argument"); return 1; } var = *wp++; if (!var) { bi_errorf("missing name argument"); return 1; } if (!*var || *skip_varname(var, TRUE)) { bi_errorf("%s: is not an identifier", var); return 1; } if (e->loc->next == (struct block *) 0) { internal_errorf(0, "c_getopts: no argv"); return 1; } /* Which arguments are we parsing... */ if (*wp == (char *) 0) wp = e->loc->next->argv; else *--wp = e->loc->next->argv[0]; /* Check that our saved state won't cause a core dump... */ for (argc = 0; wp[argc]; argc++) ; if (user_opt.optind > argc || (user_opt.p != 0 && user_opt.p > strlen(wp[user_opt.optind - 1]))) { bi_errorf("arguments changed since last call"); return 1; } user_opt.optarg = (char *) 0; optc = ksh_getopt(wp, &user_opt, options); if (optc >= 0 && optc != '?' && (user_opt.info & GI_PLUS)) { buf[0] = '+'; buf[1] = optc; buf[2] = '\0'; } else { /* POSIX says var is set to ? at end-of-options, at&t ksh * sets it to null - we go with POSIX... */ buf[0] = optc < 0 ? '?' : optc; buf[1] = '\0'; } /* at&t ksh does not change OPTIND if it was an unknown option. * Scripts counting on this are prone to break... (ie, don't count * on this staying). */ if (optc != '?') { user_opt.uoptind = user_opt.optind; } voptarg = global("OPTARG"); voptarg->flag &= ~RDONLY; /* at&t ksh clears ro and int */ /* Paranoia: ensure no bizarre results. */ if (voptarg->flag & INTEGER) typeset("OPTARG", 0, INTEGER, 0, 0); if (user_opt.optarg == (char *) 0) unset(voptarg, 0); else /* This can't fail (have cleared readonly/integer) */ setstr(voptarg, user_opt.optarg, KSH_RETURN_ERROR); ret = 0; vq = global(var); /* Error message already printed (integer, readonly) */ if (!setstr(vq, buf, KSH_RETURN_ERROR)) ret = 1; if (Flag(FEXPORT)) typeset(var, EXPORT, 0, 0, 0); return optc < 0 ? 1 : ret;}#ifdef EMACSintc_bind(wp) char **wp;{ int rv = 0, macro = 0, list = 0; register char *cp; int optc; while ((optc = ksh_getopt(wp, &builtin_opt, "lm")) != EOF) switch (optc) { case 'l': list = 1; break; case 'm': macro = 1; break; case '?': return 1; } wp += builtin_opt.optind; if (*wp == NULL) /* list all */ rv = x_bind((char*)NULL, (char*)NULL, 0, list); for (; *wp != NULL; wp++) { cp = strchr(*wp, '='); if (cp != NULL) *cp++ = '\0'; if (x_bind(*wp, cp, macro, 0)) rv = 1; } return rv;}#endif/* A leading = means assignments before command are kept; * a leading * means a POSIX special builtin; * a leading + means a POSIX regular builtin * (* and + should not be combined). */const struct builtin kshbuiltins [] = { {"+alias", c_alias}, /* no =: at&t manual wrong */ {"+cd", c_cd}, {"+command", c_command}, {"echo", c_print}, {"*=export", c_typeset},#ifdef HISTORY {"+fc", c_fc},#endif /* HISTORY */ {"+getopts", c_getopts}, {"+jobs", c_jobs}, {"+kill", c_kill},#ifdef KSH {"let", c_let},#endif /* KSH */ {"print", c_print}, {"pwd", c_pwd}, {"*=readonly", c_typeset}, {"=typeset", c_typeset}, {"+unalias", c_unalias}, {"whence", c_whence},#ifdef JOBS {"+bg", c_fgbg}, {"+fg", c_fgbg},#endif#ifdef EMACS {"bind", c_bind},#endif {NULL, NULL}};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -