void semicolon_arrfixenv(char *s, char **t) { char **ep, *u; int len_s; Param pm; MUSTUSEHEAP("semicolon_arrfixenv"); if (t == path) cmdnamtab->emptytable(cmdnamtab); u = zjoin(t, ';'); len_s = strlen(s); pm = (Param) paramtab->getnode(paramtab, s); for (ep = environ; *ep; ep++) if (!strncmp(*ep, s, len_s) && (*ep)[len_s] == '=') { pm->env = replenv(*ep, u); // (void)SetEnvironmentVariable(*ep,u); return; } if (isset(ALLEXPORT)) pm->flags |= PM_EXPORTED; if (pm->flags & PM_EXPORTED) { pm->env = addenv(s, u); (void)SetEnvironmentVariable(s,u); } }
static char * get_zle_state(UNUSED(Param pm)) { char *zle_state = NULL, *ptr = NULL, **arr = NULL; int itp, istate, len = 0; /* * Substrings are sorted at the end, so the user can * easily match against this parameter: * if [[ $ZLE_STATE == *bar*foo*zonk* ]]; then ...; fi */ for (itp = 0; itp < 2; itp++) { char *str; for (istate = 0; istate < 2; istate++) { int slen; switch (istate) { case 0: if (insmode) { str = "insert"; } else { str = "overwrite"; } break; case 1: if (hist_skip_flags & HIST_FOREIGN) { str = "localhistory"; } else { str = "globalhistory"; } break; default: str = ""; } slen = strlen(str); if (itp == 0) { /* Accumulating length */ if (istate) len++; /* for space */ len += slen; } else { /* Accumulating string */ if (istate) *ptr++ = ':'; memcpy(ptr, str, slen); ptr += slen; } } if (itp == 0) { len++; /* terminating NULL */ ptr = zle_state = (char *)zhalloc(len); } else { *ptr = '\0'; } } arr = colonsplit(zle_state, 0); strmetasort(arr, SORTIT_ANYOLDHOW, NULL); zle_state = zjoin(arr, ' ', 1); freearray(arr); return zle_state; }
static int bin_sched(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) { char *s, **argptr; time_t t; long h, m, sec; struct tm *tm; struct schedcmd *sch, *sch2, *schl; int sn, flags = 0; /* If the argument begins with a -, remove the specified item from the schedule. */ for (argptr = argv; *argptr && **argptr == '-'; argptr++) { char *arg = *argptr + 1; if (idigit(*arg)) { sn = atoi(arg); if (!sn) { zwarnnam("sched", "usage for delete: sched -<item#>."); return 1; } for (schl = NULL, sch = schedcmds, sn--; sch && sn; sch = (schl = sch)->next, sn--); if (!sch) { zwarnnam("sched", "not that many entries"); return 1; } if (schl) schl->next = sch->next; else { scheddeltimed(); schedcmds = sch->next; if (schedcmds) { DPUTS(timedfns && firstnode(timedfns), "BUG: already timed fn (2)"); schedaddtimed(schedcmds->time); } } zsfree(sch->cmd); zfree(sch, sizeof(struct schedcmd)); return 0; } else if (*arg == '-') { /* end of options */ argptr++; break; } else if (!strcmp(arg, "o")) { flags |= SCHEDFLAG_TRASH_ZLE; } else { if (*arg) zwarnnam(nam, "bad option: -%c", *arg); else zwarnnam(nam, "option expected"); return 1; } } /* given no arguments, display the schedule list */ if (!*argptr) { for (sn = 1, sch = schedcmds; sch; sch = sch->next, sn++) { char tbuf[60], *flagstr, *endstr; time_t t; struct tm *tmp; t = sch->time; tmp = localtime(&t); ztrftime(tbuf, 40, "%a %b %e %k:%M:%S", tmp, 0L); if (sch->flags & SCHEDFLAG_TRASH_ZLE) flagstr = "-o "; else flagstr = ""; if (*sch->cmd == '-') endstr = "-- "; else endstr = ""; printf("%3d %s %s%s%s\n", sn, tbuf, flagstr, endstr, sch->cmd); } return 0; } else if (!argptr[1]) { /* other than the two cases above, sched * *requires at least two arguments */ zwarnnam("sched", "not enough arguments"); return 1; } /* The first argument specifies the time to schedule the command for. The remaining arguments form the command. */ s = *argptr++; if (*s == '+') { /* * + introduces a relative time. The rest of the argument may be an * hour:minute offset from the current time. Once the hour and minute * numbers have been extracted, and the format verified, the resulting * offset is simply added to the current time. */ zlong zl = zstrtol(s + 1, &s, 10); if (*s == ':') { m = (long)zstrtol(s + 1, &s, 10); if (*s == ':') sec = (long)zstrtol(s + 1, &s, 10); else sec = 0; if (*s) { zwarnnam("sched", "bad time specifier"); return 1; } t = time(NULL) + (long)zl * 3600 + m * 60 + sec; } else if (!*s) { /* * Alternatively, it may simply be a number of seconds. * This is here for consistency with absolute times. */ t = time(NULL) + (time_t)zl; } else { zwarnnam("sched", "bad time specifier"); return 1; } } else { /* * If there is no +, an absolute time must have been given. * This may be in hour:minute format, optionally followed by a string * starting with `a' or `p' (for a.m. or p.m.). Characters after the * `a' or `p' are ignored. */ zlong zl = zstrtol(s, &s, 10); if (*s == ':') { h = (long)zl; m = (long)zstrtol(s + 1, &s, 10); if (*s == ':') sec = (long)zstrtol(s + 1, &s, 10); else sec = 0; if (*s && *s != 'a' && *s != 'A' && *s != 'p' && *s != 'P') { zwarnnam("sched", "bad time specifier"); return 1; } t = time(NULL); tm = localtime(&t); t -= tm->tm_sec + tm->tm_min * 60 + tm->tm_hour * 3600; if (*s == 'p' || *s == 'P') h += 12; t += h * 3600 + m * 60 + sec; /* * If the specified time is before the current time, it must refer * to tomorrow. */ if (t < time(NULL)) t += 3600 * 24; } else if (!*s) { /* * Otherwise, it must be a raw time specifier. */ t = (long)zl; } else { zwarnnam("sched", "bad time specifier"); return 1; } } /* The time has been calculated; now add the new entry to the linked list of scheduled commands. */ sch = (struct schedcmd *) zalloc(sizeof *sch); sch->time = t; sch->cmd = zjoin(argptr, ' ', 0); sch->flags = flags; /* Insert into list in time order */ if (schedcmds) { if (sch->time < schedcmds->time) { scheddeltimed(); sch->next = schedcmds; schedcmds = sch; DPUTS(timedfns && firstnode(timedfns), "BUG: already timed fn (3)"); schedaddtimed(t); } else { for (sch2 = schedcmds; sch2->next && sch2->next->time < sch->time; sch2 = sch2->next) ; sch->next = sch2->next; sch2->next = sch; } } else { sch->next = NULL; schedcmds = sch; DPUTS(timedfns && firstnode(timedfns), "BUG: already timed fn (4)"); schedaddtimed(t); } return 0; }
static int newptycmd(char *nam, char *pname, char **args, int echo, int nblock) { Ptycmd p; int master, slave, pid, oineval = ineval, ret; char *oscriptname = scriptname, syncch; Eprog prog; /* code borrowed from bin_eval() */ ineval = !isset(EVALLINENO); if (!ineval) scriptname = "(zpty)"; prog = parse_string(zjoin(args, ' ', 1), 0); if (!prog) { errflag &= ~ERRFLAG_ERROR; scriptname = oscriptname; ineval = oineval; return 1; } if (get_pty(1, &master)) { zwarnnam(nam, "can't open pseudo terminal: %e", errno); scriptname = oscriptname; ineval = oineval; return 1; } if ((pid = fork()) == -1) { zwarnnam(nam, "can't create pty command %s: %e", pname, errno); close(master); scriptname = oscriptname; ineval = oineval; return 1; } else if (!pid) { /* This code copied from the clone module, except for getting * * the descriptor from get_pty() and duplicating it to 0/1/2. */ deletehookfunc("exit", ptyhook); clearjobtab(0); ppid = getppid(); mypid = getpid(); #ifdef HAVE_SETSID if (setsid() != mypid) { zwarnnam(nam, "failed to create new session: %e", errno); #endif #ifdef TIOCNOTTY if (ioctl(SHTTY, TIOCNOTTY, 0)) zwarnnam(nam, "%e", errno); setpgrp(0L, mypid); #endif #ifdef HAVE_SETSID } #endif if (get_pty(0, &slave)) exit(1); SHTTY = slave; attachtty(mypid); #ifdef TIOCGWINSZ /* Set the window size before associating with the terminal * * so that we don't get hit with a SIGWINCH. I'm paranoid. */ if (interact) { struct ttyinfo info; if (ioctl(slave, TIOCGWINSZ, (char *) &info.winsize) == 0) { info.winsize.ws_row = zterm_lines; info.winsize.ws_col = zterm_columns; ioctl(slave, TIOCSWINSZ, (char *) &info.winsize); } } #endif /* TIOCGWINSZ */ if (!echo) { struct ttyinfo info; if (!ptygettyinfo(slave, &info)) { #ifdef HAVE_TERMIOS_H info.tio.c_lflag &= ~ECHO; #else #ifdef HAVE_TERMIO_H info.tio.c_lflag &= ~ECHO; #else info.tio.lmodes &= ~ECHO; /**** dunno if this is right */ #endif #endif ptysettyinfo(slave, &info); } } #ifdef TIOCSCTTY ioctl(slave, TIOCSCTTY, 0); #endif close(0); close(1); close(2); dup2(slave, 0); dup2(slave, 1); dup2(slave, 2); closem(FDT_UNUSED, 0); close(slave); close(master); close(coprocin); close(coprocout); init_io(NULL); setsparam("TTY", ztrdup(ttystrname)); opts[INTERACTIVE] = 0; syncch = 0; do { ret = write(1, &syncch, 1); } while (ret != 1 && ( #ifdef EWOULDBLOCK errno == EWOULDBLOCK || #else #ifdef EAGAIN errno == EAGAIN || #endif #endif errno == EINTR)); execode(prog, 1, 0, "zpty"); stopmsg = 2; mypid = 0; /* trick to ensure we _exit() */ zexit(lastval, 0); } master = movefd(master); if (master == -1) { zerrnam(nam, "cannot duplicate fd %d: %e", master, errno); scriptname = oscriptname; ineval = oineval; return 1; } p = (Ptycmd) zalloc(sizeof(*p)); p->name = ztrdup(pname); p->args = zarrdup(args); p->fd = master; p->pid = pid; p->echo = echo; p->nblock = nblock; p->fin = 0; p->read = -1; p->old = NULL; p->olen = 0; p->next = ptycmds; ptycmds = p; if (nblock) ptynonblock(master); scriptname = oscriptname; ineval = oineval; do { ret = read(master, &syncch, 1); } while (ret != 1 && ( #ifdef EWOULDBLOCK errno == EWOULDBLOCK || #else #ifdef EAGAIN errno == EAGAIN || #endif #endif errno == EINTR)); setiparam_no_convert("REPLY", (zlong)master); return 0; }
char * semicolonarrgetfn(Param pm) { return zjoin(*(char ***)pm->data, ';'); }