1: /* Copyright (c) 1979 Regents of the University of California */
   2: static char *sccsid = "@(#)ex_unix.c	6.1 10/18/80";
   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:     if (!(status & 0377)) {
 321:         status = (status >> 8) & 0377;
 322:     } else {
 323:         printf("%d: terminated with signal %d",pid,status & 0177);
 324:         if (status & 0200)
 325:             printf(" -- core dumped");
 326:         putchar('\n');
 327:     }
 328: }
 329: 
 330: /*
 331:  * The end of a recover operation.  If the process
 332:  * exits non-zero, force not edited; otherwise force
 333:  * a write.
 334:  */
 335: revocer()
 336: {
 337: 
 338:     waitfor();
 339:     if (pid == rpid && status != 0)
 340:         edited = 0;
 341:     else
 342:         change();
 343: }

Defined functions

filter defined in line 231; used 4 times
recover defined in line 285; used 1 times
revocer defined in line 335; used 1 times
unix0 defined in line 16; used 5 times
unixex defined in line 125; used 4 times
unixwt defined in line 204; used 3 times
waitfor defined in line 314; used 4 times

Defined variables

sccsid defined in line 2; never used
Last modified: 1982-01-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1385
Valid CSS Valid XHTML 1.0 Strict