static List *backq(Node *ifs, Node *n) { int p[2], sp; pid_t pid; List *bq; struct termios t; if (n == NULL) return NULL; if (pipe(p) < 0) { uerror("pipe"); rc_error(NULL); } if (interactive) tcgetattr(0, &t); if ((pid = rc_fork()) == 0) { mvfd(p[1], 1); close(p[0]); redirq = NULL; walk(n, FALSE); exit(getstatus()); } close(p[1]); bq = bqinput(glom(ifs), p[0]); close(p[0]); rc_wait4(pid, &sp, TRUE); if (interactive && WIFSIGNALED(sp)) tcsetattr(0, TCSANOW, &t); statprint(-1, sp); varassign("bqstatus", word(strstatus(sp), NULL), FALSE); sigchk(); return bq; }
extern void setpipestatus(int stats[], int num) { int i; for (i = 0; i < (pipelength = num); i++) { statprint(-1, stats[i]); statuses[i] = stats[i]; } }
extern void setstatus(int pid, int i) { pipelength = 1; statuses[0] = i; statprint(pid, i); }
static int bin_stat(char *name, char **args, Options ops, UNUSED(int func)) { char **aptr, *arrnam = NULL, **array = NULL, **arrptr = NULL; char *hashnam = NULL, **hash = NULL, **hashptr = NULL; int len, iwhich = -1, ret = 0, flags = 0, arrsize = 0, fd = 0; struct stat statbuf; int found = 0, nargs; timefmt = "%a %b %e %k:%M:%S %Z %Y"; for (; *args && (**args == '+' || **args == '-'); args++) { char *arg = *args+1; if (!*arg || *arg == '-' || *arg == '+') { args++; break; } if (**args == '+') { if (found) break; len = strlen(arg); for (aptr = statelts; *aptr; aptr++) if (!strncmp(*aptr, arg, len)) { found++; iwhich = aptr - statelts; } if (found > 1) { zwarnnam(name, "%s: ambiguous stat element", arg); return 1; } else if (found == 0) { zwarnnam(name, "%s: no such stat element", arg); return 1; } /* if name of link requested, turn on lstat */ if (iwhich == ST_READLINK) ops->ind['L'] = 1; flags |= STF_PICK; } else { for (; *arg; arg++) { if (strchr("glLnNorstT", *arg)) ops->ind[STOUC(*arg)] = 1; else if (*arg == 'A') { if (arg[1]) { arrnam = arg+1; } else if (!(arrnam = *++args)) { zwarnnam(name, "missing parameter name"); return 1; } flags |= STF_ARRAY; break; } else if (*arg == 'H') { if (arg[1]) { hashnam = arg+1; } else if (!(hashnam = *++args)) { zwarnnam(name, "missing parameter name"); return 1; } flags |= STF_HASH; break; } else if (*arg == 'f') { char *sfd; ops->ind['f'] = 1; if (arg[1]) { sfd = arg+1; } else if (!(sfd = *++args)) { zwarnnam(name, "missing file descriptor"); return 1; } fd = zstrtol(sfd, &sfd, 10); if (*sfd) { zwarnnam(name, "bad file descriptor"); return 1; } break; } else if (*arg == 'F') { if (arg[1]) { timefmt = arg+1; } else if (!(timefmt = *++args)) { zwarnnam(name, "missing time format"); return 1; } /* force string format in order to use time format */ ops->ind['s'] = 1; break; } else { zwarnnam(name, "bad option: -%c", *arg); return 1; } } } } if ((flags & STF_ARRAY) && (flags & STF_HASH)) { /* We don't implement setting multiple variables at once */ zwarnnam(name, "both array and hash requested"); return 1; /* Alternate method would be to make -H blank arrnam etc etc * * and so get 'silent loss' of earlier choice, which would * * be similar to stat -A foo -A bar filename */ } if (OPT_ISSET(ops,'l')) { /* list types and return: can also list to array */ if (arrnam) { arrptr = array = (char **)zalloc((ST_COUNT+1)*sizeof(char *)); array[ST_COUNT] = NULL; } for (aptr = statelts; *aptr; aptr++) { if (arrnam) { *arrptr++ = ztrdup(*aptr); } else { printf("%s", *aptr); if (aptr[1]) putchar(' '); } } if (arrnam) { setaparam(arrnam, array); if (errflag) return 1; } else putchar('\n'); return 0; } if (!*args && !OPT_ISSET(ops,'f')) { zwarnnam(name, "no files given"); return 1; } else if (*args && OPT_ISSET(ops,'f')) { zwarnnam(name, "no files allowed with -f"); return 1; } nargs = 0; if (OPT_ISSET(ops,'f')) nargs = 1; else for (aptr = args; *aptr; aptr++) nargs++; if (OPT_ISSET(ops,'g')) { flags |= STF_GMT; ops->ind['s'] = 1; } if (OPT_ISSET(ops,'s') || OPT_ISSET(ops,'r')) flags |= STF_STRING; if (OPT_ISSET(ops,'r') || !OPT_ISSET(ops,'s')) flags |= STF_RAW; if (OPT_ISSET(ops,'n')) flags |= STF_FILE; if (OPT_ISSET(ops,'o')) flags |= STF_OCTAL; if (OPT_ISSET(ops,'t')) flags |= STF_NAME; if (!(arrnam || hashnam)) { if (nargs > 1) flags |= STF_FILE; if (!(flags & STF_PICK)) flags |= STF_NAME; } if (OPT_ISSET(ops,'N') || OPT_ISSET(ops,'f')) flags &= ~STF_FILE; if (OPT_ISSET(ops,'T') || OPT_ISSET(ops,'H')) flags &= ~STF_NAME; if (hashnam) { if (nargs > 1) { zwarnnam(name, "only one file allowed with -H"); return 1; } arrsize = (flags & STF_PICK) ? 1 : ST_COUNT; if (flags & STF_FILE) arrsize++; hashptr = hash = (char **)zshcalloc((arrsize+1)*2*sizeof(char *)); } if (arrnam) { arrsize = (flags & STF_PICK) ? 1 : ST_COUNT; if (flags & STF_FILE) arrsize++; arrsize *= nargs; arrptr = array = (char **)zshcalloc((arrsize+1)*sizeof(char *)); } for (; OPT_ISSET(ops,'f') || *args; args++) { char outbuf[PATH_MAX + 9]; /* "link " + link name + NULL */ int rval = OPT_ISSET(ops,'f') ? fstat(fd, &statbuf) : OPT_ISSET(ops,'L') ? lstat(unmeta(*args), &statbuf) : stat(unmeta(*args), &statbuf); if (rval) { if (OPT_ISSET(ops,'f')) sprintf(outbuf, "%d", fd); zwarnnam(name, "%s: %e", OPT_ISSET(ops,'f') ? outbuf : *args, errno); ret = 1; if (OPT_ISSET(ops,'f') || arrnam) break; else continue; } if (flags & STF_FILE) { if (arrnam) *arrptr++ = ztrdup(*args); else if (hashnam) { *hashptr++ = ztrdup(HNAMEKEY); *hashptr++ = ztrdup(*args); } else printf("%s%s", *args, (flags & STF_PICK) ? " " : ":\n"); } if (iwhich > -1) { statprint(&statbuf, outbuf, *args, iwhich, flags); if (arrnam) *arrptr++ = metafy(outbuf, -1, META_DUP); else if (hashnam) { /* STF_NAME explicitly turned off for ops.ind['H'] above */ *hashptr++ = ztrdup(statelts[iwhich]); *hashptr++ = metafy(outbuf, -1, META_DUP); } else printf("%s\n", outbuf); } else { int i; for (i = 0; i < ST_COUNT; i++) { statprint(&statbuf, outbuf, *args, i, flags); if (arrnam) *arrptr++= metafy(outbuf, -1, META_DUP); else if (hashnam) { /* STF_NAME explicitly turned off for ops.ind['H'] above */ *hashptr++ = ztrdup(statelts[i]); *hashptr++ = metafy(outbuf, -1, META_DUP); } else printf("%s\n", outbuf); } } if (OPT_ISSET(ops,'f')) break; if (!arrnam && !hashnam && args[1] && !(flags & STF_PICK)) putchar('\n'); } if (arrnam) { if (ret) freearray(array); else { setaparam(arrnam, array); if (errflag) return 1; } } if (hashnam) { if (ret) freearray(hash); else { sethparam(hashnam, hash); if (errflag) return 1; } } return ret; }