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

unix.superglobalmegacorp.com

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