Annotation of 42BSD/ucb/ex/ex_unix.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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