Annotation of 43BSDReno/usr.bin/ex/ex_unix.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char *sccsid = "@(#)ex_unix.c   7.8 (Berkeley) 7/28/88";
                      9: #endif not lint
                     10: 
                     11: #include "ex.h"
                     12: #include "ex_temp.h"
                     13: #include "ex_tty.h"
                     14: #include "ex_vis.h"
                     15: #include <sys/wait.h>
                     16: 
                     17: /*
                     18:  * Unix escapes, filtering
                     19:  */
                     20: 
                     21: /*
                     22:  * First part of a shell escape,
                     23:  * parse the line, expanding # and % and ! and printing if implied.
                     24:  */
                     25: unix0(warn)
                     26:        bool warn;
                     27: {
                     28:        register char *up, *fp;
                     29:        register short c;
                     30:        char printub, puxb[UXBSIZE + sizeof (int)];
                     31: 
                     32:        printub = 0;
                     33:        CP(puxb, uxb);
                     34:        c = ex_getchar();
                     35:        if (c == '\n' || c == EOF)
                     36:                error("Incomplete shell escape command@- use 'shell' to get a shell");
                     37:        up = uxb;
                     38:        do {
                     39:                switch (c) {
                     40: 
                     41:                case '\\':
                     42:                        if (any(peekchar(), "%#!"))
                     43:                                c = ex_getchar();
                     44:                default:
                     45:                        if (up >= &uxb[UXBSIZE]) {
                     46: tunix:
                     47:                                uxb[0] = 0;
                     48:                                error("Command too long");
                     49:                        }
                     50:                        *up++ = c;
                     51:                        break;
                     52: 
                     53:                case '!':
                     54:                        fp = puxb;
                     55:                        if (*fp == 0) {
                     56:                                uxb[0] = 0;
                     57:                                error("No previous command@to substitute for !");
                     58:                        }
                     59:                        printub++;
                     60:                        while (*fp) {
                     61:                                if (up >= &uxb[UXBSIZE])
                     62:                                        goto tunix;
                     63:                                *up++ = *fp++;
                     64:                        }
                     65:                        break;
                     66: 
                     67:                case '#':
                     68:                        fp = altfile;
                     69:                        if (*fp == 0) {
                     70:                                uxb[0] = 0;
                     71:                                error("No alternate filename@to substitute for #");
                     72:                        }
                     73:                        goto uexp;
                     74: 
                     75:                case '%':
                     76:                        fp = savedfile;
                     77:                        if (*fp == 0) {
                     78:                                uxb[0] = 0;
                     79:                                error("No filename@to substitute for %%");
                     80:                        }
                     81: uexp:
                     82:                        printub++;
                     83:                        while (*fp) {
                     84:                                if (up >= &uxb[UXBSIZE])
                     85:                                        goto tunix;
                     86:                                *up++ = *fp++ | QUOTE;
                     87:                        }
                     88:                        break;
                     89:                }
                     90:                c = ex_getchar();
                     91:        } while (c == '"' || c == '|' || !endcmd(c));
                     92:        if (c == EOF)
                     93:                ungetchar(c);
                     94:        *up = 0;
                     95:        if (!inopen)
                     96:                resetflav();
                     97:        if (warn)
                     98:                ckaw();
                     99:        if (warn && hush == 0 && chng && xchng != chng && value(WARN) && dol > zero) {
                    100:                xchng = chng;
                    101:                vnfl();
                    102:                ex_printf(mesg("[No write]|[No write since last change]"));
                    103:                noonl();
                    104:                flush();
                    105:        } else
                    106:                warn = 0;
                    107:        if (printub) {
                    108:                if (uxb[0] == 0)
                    109:                        error("No previous command@to repeat");
                    110:                if (inopen) {
                    111:                        splitw++;
                    112:                        vclean();
                    113:                        vgoto(WECHO, 0);
                    114:                }
                    115:                if (warn)
                    116:                        vnfl();
                    117:                if (hush == 0)
                    118:                        lprintf("!%s", uxb);
                    119:                if (inopen && Outchar != termchar) {
                    120:                        vclreol();
                    121:                        vgoto(WECHO, 0);
                    122:                } else
                    123:                        putnl();
                    124:                flush();
                    125:        }
                    126: }
                    127: 
                    128: /*
                    129:  * Do the real work for execution of a shell escape.
                    130:  * Mode is like the number passed to open system calls
                    131:  * and indicates filtering.  If input is implied, newstdin
                    132:  * must have been setup already.
                    133:  */
                    134: ttymode
                    135: unixex(opt, up, newstdin, mode)
                    136:        char *opt, *up;
                    137:        int newstdin, mode;
                    138: {
                    139:        int pvec[2];
                    140:        ttymode f;
                    141: 
                    142:        signal(SIGINT, SIG_IGN);
                    143: #ifdef SIGTSTP
                    144:        if (dosusp)
                    145:                signal(SIGTSTP, SIG_DFL);
                    146: #endif
                    147:        if (inopen)
                    148:                f = setty(normf);
                    149:        if ((mode & 1) && pipe(pvec) < 0) {
                    150:                /* Newstdin should be io so it will be closed */
                    151:                if (inopen)
                    152:                        ignore(setty(f));
                    153:                error("Can't make pipe for filter");
                    154:        }
                    155: #ifndef VFORK
                    156:        pid = fork();
                    157: #else
                    158:        pid = vfork();
                    159: #endif
                    160:        if (pid < 0) {
                    161:                if (mode & 1) {
                    162:                        close(pvec[0]);
                    163:                        close(pvec[1]);
                    164:                }
                    165:                setrupt();
                    166:                error("No more processes");
                    167:        }
                    168:        if (pid == 0) {
                    169:                if (up) {
                    170:                        register char *cp = up;
                    171:                        while (*cp)
                    172:                                *cp++ &= TRIM;
                    173:                }
                    174:                if (mode & 2) {
                    175:                        close(0);
                    176:                        dup(newstdin);
                    177:                        close(newstdin);
                    178:                }
                    179:                if (mode & 1) {
                    180:                        close(pvec[0]);
                    181:                        close(1);
                    182:                        dup(pvec[1]);
                    183:                        if (inopen) {
                    184:                                close(2);
                    185:                                dup(1);
                    186:                        }
                    187:                        close(pvec[1]);
                    188:                }
                    189:                if (io)
                    190:                        close(io);
                    191:                if (tfile)
                    192:                        close(tfile);
                    193: #ifdef EXSTRINGS
                    194:                close(erfile);
                    195: #endif
                    196:                signal(SIGHUP, oldhup);
                    197:                signal(SIGQUIT, oldquit);
                    198:                if (ruptible)
                    199:                        signal(SIGINT, SIG_DFL);
                    200:                execl(svalue(SHELL), "sh", opt, up, (char *) 0);
                    201:                ex_printf("No %s!\n", svalue(SHELL));
                    202:                error(NOSTR);
                    203:        }
                    204:        if (mode & 1) {
                    205:                io = pvec[0];
                    206:                close(pvec[1]);
                    207:        }
                    208:        if (newstdin)
                    209:                close(newstdin);
                    210:        return (f);
                    211: }
                    212: 
                    213: /*
                    214:  * Wait for the command to complete.
                    215:  * F is for restoration of tty mode if from open/visual.
                    216:  * C flags suppression of printing.
                    217:  */
                    218: unixwt(c, f)
                    219:        bool c;
                    220:        ttymode f;
                    221: {
                    222: 
                    223:        waitfor();
                    224: #ifdef SIGTSTP
                    225:        if (dosusp)
                    226:                signal(SIGTSTP, onsusp);
                    227: #endif
                    228:        if (inopen)
                    229:                ignore(setty(f));
                    230:        setrupt();
                    231:        if (!inopen && c && hush == 0) {
                    232:                ex_printf("!\n");
                    233:                flush();
                    234:                termreset();
                    235:                gettmode();
                    236:        }
                    237: }
                    238: 
                    239: /*
                    240:  * Setup a pipeline for the filtration implied by mode
                    241:  * which is like a open number.  If input is required to
                    242:  * the filter, then a child editor is created to write it.
                    243:  * If output is catch it from io which is created by unixex.
                    244:  */
                    245: filter(mode)
                    246:        register int mode;
                    247: {
                    248:        static int pvec[2];
                    249:        ttymode f;      /* mjm: was register */
                    250:        register int lines = lineDOL();
                    251:        struct stat statb;
                    252: 
                    253:        mode++;
                    254:        if (mode & 2) {
                    255:                signal(SIGINT, SIG_IGN);
                    256:                if (pipe(pvec) < 0)
                    257:                        error("Can't make pipe");
                    258:                pid = fork();
                    259:                io = pvec[0];
                    260:                if (pid < 0) {
                    261:                        setrupt();
                    262:                        close(pvec[1]);
                    263:                        error("No more processes");
                    264:                }
                    265:                if (pid == 0) {
                    266:                        setrupt();
                    267:                        io = pvec[1];
                    268:                        close(pvec[0]);
                    269:                        putfile(1);
                    270:                        ex_exit(0);
                    271:                }
                    272:                close(pvec[1]);
                    273:                io = pvec[0];
                    274:                setrupt();
                    275:        }
                    276:        f = unixex("-c", uxb, (mode & 2) ? pvec[0] : 0, mode);
                    277:        if (mode == 3) {
                    278:                ex_delete(0);
                    279:                addr2 = addr1 - 1;
                    280:        }
                    281:        if (mode & 1) {
                    282:                if(FIXUNDO)
                    283:                        undap1 = undap2 = addr2+1;
                    284:                if (fstat(io, &statb) < 0)
                    285:                        bsize = LBSIZE;
                    286:                else {
                    287:                        bsize = statb.st_blksize;
                    288:                        if (bsize <= 0)
                    289:                                bsize = LBSIZE;
                    290:                }
                    291:                ignore(append(getfile, addr2));
                    292: #ifdef TRACE
                    293:                if (trace)
                    294:                        vudump("after append in filter");
                    295: #endif
                    296:        }
                    297:        close(io);
                    298:        io = -1;
                    299:        unixwt(!inopen, f);
                    300:        netchHAD(lines);
                    301: }
                    302: 
                    303: /*
                    304:  * Set up to do a recover, getting io to be a pipe from
                    305:  * the recover process.
                    306:  */
                    307: recover()
                    308: {
                    309:        static int pvec[2];
                    310: 
                    311:        if (pipe(pvec) < 0)
                    312:                error(" Can't make pipe for recovery");
                    313:        pid = fork();
                    314:        io = pvec[0];
                    315:        if (pid < 0) {
                    316:                close(pvec[1]);
                    317:                error(" Can't fork to execute recovery");
                    318:        }
                    319:        if (pid == 0) {
                    320:                close(2);
                    321:                dup(1);
                    322:                close(1);
                    323:                dup(pvec[1]);
                    324:                close(pvec[1]);
                    325:                execl(_PATH_EXRECOVER, "exrecover", svalue(DIRECTORY),
                    326:                    file, (char *) 0);
                    327:                close(1);
                    328:                dup(2);
                    329:                error(" No recovery routine");
                    330:        }
                    331:        close(pvec[1]);
                    332: }
                    333: 
                    334: /*
                    335:  * Wait for the process (pid an external) to complete.
                    336:  */
                    337: waitfor()
                    338: {
                    339:        union wait stat, pstat;
                    340:        int wpid;
                    341:        extern char *sys_siglist[];
                    342: 
                    343:        pstat.w_status = 0;
                    344:        do {
                    345:                wpid = wait(&stat);
                    346:                if (wpid == pid) {
                    347:                        pstat = stat;
                    348:                        rpid = wpid;
                    349:                }
                    350:        } while (wpid != -1);
                    351: 
                    352:        if (WIFEXITED(pstat))
                    353:                status = pstat.w_retcode;
                    354:        else {
                    355:                ex_printf("%d: terminated abnormally: %s ",
                    356:                    pid, sys_siglist[pstat.w_termsig]);
                    357:                if (pstat.w_coredump)
                    358:                        ex_printf("(core dumped) ");
                    359:                if (!inopen)
                    360:                        ex_printf("\r\n");
                    361:                status = pstat.w_termsig;
                    362:        }
                    363: }
                    364: 
                    365: /*
                    366:  * The end of a recover operation.  If the process
                    367:  * exits non-zero, force not edited; otherwise force
                    368:  * a write.
                    369:  */
                    370: revocer()
                    371: {
                    372: 
                    373:        waitfor();
                    374:        if (pid == rpid && status != 0)
                    375:                edited = 0;
                    376:        else
                    377:                change();
                    378: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.