/* * This routine initializes the current and standard screen. */ WINDOW * initscr() { char *sp; int nfd; # ifdef DEBUG fprintf(outf, "INITSCR()\n"); # endif if (My_term) setterm(Def_term); else { nfd = getdtablesize(); for (_tty_ch = 0; _tty_ch < nfd; _tty_ch++) if (isatty(_tty_ch)) break; gettmode(); sp = getenv("TERM"); if (! sp) sp = Def_term; setterm(sp); # ifdef DEBUG fprintf(outf, "INITSCR: term = %s\n", sp); # endif } _puts(TI); _puts(VS); # ifdef SIGTSTP signal(SIGTSTP, (sig_t)tstp); # endif if (curscr != NULL) { # ifdef DEBUG fprintf(outf, "INITSCR: curscr = 0%o\n", curscr); # endif delwin(curscr); } # ifdef DEBUG fprintf(outf, "LINES = %d, COLS = %d\n", LINES, COLS); # endif if ((curscr = newwin(LINES, COLS, 0, 0)) == ERR) return ERR; clearok(curscr, TRUE); curscr->_flags &= ~_FULLLINE; if (stdscr != NULL) { # ifdef DEBUG fprintf(outf, "INITSCR: stdscr = 0%o\n", stdscr); # endif delwin(stdscr); } stdscr = newwin(LINES, COLS, 0, 0); return stdscr; }
void viquotedinsert(void) { #ifndef WINNT #ifndef HAS_TIO struct sgttyb sob; #endif #endif /* WINNT */ spaceinline(1); line[cs] = '^'; refresh(); #ifndef WINNT #ifndef HAS_TIO sob = shttyinfo.sgttyb; sob.sg_flags = (sob.sg_flags | RAW) & ~ECHO; ioctl(SHTTY, TIOCSETN, &sob); #endif #endif /* WINNT */ c = getkey(0); #ifndef WINNT #ifndef HAS_TIO setterm(); #endif #endif /* WINNT */ foredel(1); if(c < 0) feep(); else selfinsert(); }
main() { reg char *sp; char *getenv(); int _putchar(), die(); srand(getpid()); /* initialize random sequence */ if (isatty(0)) { gettmode(); if (sp=getenv("TERM")) setterm(sp); signal(SIGINT, die); } else { printf("Need a terminal on %d\n", _tty_ch); exit(1); } _puts(TI); _puts(VS); noecho(); nonl(); tputs(CL, NLINES, _putchar); for (;;) { makeboard(); /* make the board setup */ puton('*'); /* put on '*'s */ puton(' '); /* cover up with ' 's */ } }
/* * This routine initializes the current and standard screen. * * 3/5/81 (Berkeley) @(#)initscr.c 1.2 */ WINDOW * initscr() { reg char *sp; int tstp(); # ifdef DEBUG fprintf(outf, "INITSCR()\n"); # endif if (!My_term && isatty(2)) { _tty_ch = 2; gettmode(); if ((sp = getenv("TERM")) == NULL) sp = Def_term; setterm(sp); # ifdef DEBUG fprintf(outf, "INITSCR: term = %s\n", sp); # endif } else setterm(Def_term); _puts(TI); _puts(VS); # ifdef SIGTSTP signal(SIGTSTP, tstp); # endif if (curscr != NULL) { # ifdef DEBUG fprintf(outf, "INITSCR: curscr = 0%o\n", curscr); # endif delwin(curscr); } # ifdef DEBUG fprintf(outf, "LINES = %d, COLS = %d\n", LINES, COLS); # endif if ((curscr = newwin(LINES, COLS, 0, 0)) == ERR) return ERR; curscr->_clear = TRUE; if (stdscr != NULL) { # ifdef DEBUG fprintf(outf, "INITSCR: stdscr = 0%o\n", stdscr); # endif delwin(stdscr); } stdscr = newwin(LINES, COLS, 0, 0); return stdscr; }
static void init(void) { char *TERM; srandom(time(NULL)); if ((TERM = getenv("TERM")) == NULL) error("TERM not set"); li = li < 0 ? 24 : li; co = co < 0 ? 80 : co; saveterm(); setterm(); }
WINDOW *initscr() { char *term; if ((term = getenv("TERM")) == NULL) return NULL; setterm(term); gettmode(); if ((_cursvar.tmpwin = newwin(LINES, COLS, 0, 0)) == (WINDOW *)ERR) return NULL; if ((curscr = newwin(LINES, COLS, 0, 0)) == (WINDOW *)ERR) return NULL; if ((stdscr = newwin(LINES, COLS, 0, 0)) == (WINDOW *)ERR) return NULL; clearok(curscr, TRUE); return(stdscr); }
void resetvideo() /**/ { int ln; static int lwinw = -1,lwinh = -1; setterm(); winw = columns-1; if (isset(SINGLELINEZLE) || !termok) winh = 1; else winh = (lines < 2) ? 24 : lines; winpos = vln = vmaxln = 0; if (lwinw != winw || lwinh != winh) { if (nbuf) { for (ln = 0; ln != lwinh; ln++) { free(nbuf[ln]); free(obuf[ln]); } free(nbuf); free(obuf); } nbuf = (char **) zalloc((winh+1)*sizeof(char *)); obuf = (char **) zalloc((winh+1)*sizeof(char *)); for (ln = 0; ln != winh+1; ln++) { nbuf[ln] = zalloc(winw+1); obuf[ln] = zalloc(winw+1); } lwinw = winw; lwinh = winh; } for (ln = 0; ln != winh+1; ln++) { *nbuf[ln] = '\0'; *obuf[ln] = '\0'; } if (!pptlen) nbuf[0][0] = obuf[0][0] = '\0'; else { for (ln = 0; ln != pptlen-1; ln++) nbuf[0][ln] = obuf[0][ln] = ' '; nbuf[0][ln] = obuf[0][ln] = '>'; nbuf[0][pptlen] = obuf[0][pptlen] = '\0'; } vcs = pptlen; olnct = nlnct = 1; }
void quotedinsert() /**/ { #ifndef TIO struct sgttyb sob; sob = shttyinfo.sgttyb; sob.sg_flags = (sob.sg_flags|RAW) & ~ECHO; ioctl(SHTTY,TIOCSETN,&sob); #endif c = getkey(0); #ifndef TIO setterm(); #endif if (c) selfinsert(); else feep(); }
/* * initscr -- * Initialize the current and standard screen. */ WINDOW * initscr() { register char *sp; #ifdef DEBUG __CTRACE("initscr\n"); #endif __echoit = 1; __pfast = __rawmode = __noqch = 0; if (gettmode() == ERR) return (NULL); /* * If My_term is set, or can't find a terminal in the environment, * use Def_term. */ if (My_term || (sp = getenv("TERM")) == NULL) sp = Def_term; if (setterm(sp) == ERR) return (NULL); /* Need either homing or cursor motion for refreshes */ if (!HO && !CM) return (NULL); if (curscr != NULL) delwin(curscr); if ((curscr = newwin(LINES, COLS, 0, 0)) == ERR) return (NULL); clearok(curscr, 1); if (stdscr != NULL) delwin(stdscr); if ((stdscr = newwin(LINES, COLS, 0, 0)) == ERR) { delwin(curscr); return (NULL); } __set_stophandler(); #ifdef DEBUG __CTRACE("initscr: LINES = %d, COLS = %d\n", LINES, COLS); #endif __startwin(); return (stdscr); }
/* * display_open: * open the display */ void display_open(void) { char *term; if (!isatty(0) || (term = getenv("TERM")) == NULL) errx(1, "no terminal type"); gettmode(); setterm(term); noecho(); cbreak(); tcgetattr(0, &saved_tty); _puts(TI); _puts(VS); #ifdef SIGTSTP signal(SIGTSTP, tstp); #endif }
void op_zedit(mval *v, mval *p) { char *edt; char es[MAX_FBUFF + 1], typ, *ptr; short path_len, tslash; int objcnt; int waitid; unsigned int childid, status; #ifdef _BSD union wait wait_status; #endif bool has_ext, exp_dir; parse_blk pblk; mstr src; zro_ent *sp, *srcdir; struct sigaction act, intr; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; if (!editor.len) { edt = GETENV("EDITOR"); if (!edt) edt = "editor"; rts_error(VARLSTCNT(4) ERR_FILENOTFND, 2, LEN_AND_STR(edt)); } MV_FORCE_STR(v); MV_FORCE_STR(p); src.len = v->str.len; src.addr = v->str.addr; if (0 == src.len) rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, src.len, src.addr); memset(&pblk, 0, SIZEOF(pblk)); pblk.buffer = es; pblk.buff_size = MAX_FBUFF; status = parse_file(&src, &pblk); if (!(status & 1)) rts_error(VARLSTCNT(5) ERR_ZEDFILSPEC, 2, src.len, src.addr, status); has_ext = 0 != (pblk.fnb & F_HAS_EXT); exp_dir = 0 != (pblk.fnb & F_HAS_DIR); if (!(pblk.fnb & F_HAS_NAME)) { assert(!has_ext); rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, pblk.b_esl, pblk.buffer); } if (!exp_dir) { memmove(&es[0], pblk.l_name, pblk.b_name + pblk.b_ext); path_len = pblk.b_name + pblk.b_ext; ptr = es; } else { path_len = pblk.b_esl; ptr = pblk.l_name; } typ = 0; if (!has_ext) { if ('.' != *ptr) { typ = STR_LIT_LEN(DOTM); if (path_len + typ > MAX_FBUFF) rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, path_len, es); memcpy(&es[path_len], DOTM, STR_LIT_LEN(DOTM)); path_len += typ; } } else { if ((STR_LIT_LEN(DOTOBJ) == pblk.b_ext) && !MEMCMP_LIT(ptr + pblk.b_name, DOTOBJ)) rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, path_len, es); else if ((STR_LIT_LEN(DOTM) == pblk.b_ext) && !MEMCMP_LIT(ptr + pblk.b_name, DOTM)) typ = STR_LIT_LEN(DOTM); } dollar_zsource.str.addr = es; dollar_zsource.str.len = path_len - typ; s2pool(&dollar_zsource.str); es[path_len] = 0; if (!exp_dir) { src.addr = es; src.len = path_len; srcdir = (zro_ent *)0; zro_search(0, 0, &src, &srcdir, TRUE); if (NULL == srcdir) { /* find the first source directory */ objcnt = (TREF(zro_root))->count; for (sp = TREF(zro_root) + 1; (NULL == srcdir) && (0 < objcnt--); ++sp) { if (ZRO_TYPE_OBJECT == sp->type) { sp++; assert(ZRO_TYPE_COUNT == sp->type); if (0 != sp->count) srcdir = sp + 1; } else { /* shared library entries (ZRO_TYPE_OBJLIB) do not have source directories */ assert(ZRO_TYPE_OBJLIB == sp->type); } } } if (srcdir && srcdir->str.len) { assert(ZRO_TYPE_SOURCE == srcdir->type); tslash = ('/' == srcdir->str.addr[srcdir->str.len - 1]) ? 0 : 1; if (path_len + srcdir->str.len + tslash >= SIZEOF(es)) rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, src.len, src.addr); memmove(&es[ srcdir->str.len + tslash], &es[0], path_len); if (tslash) es[ srcdir->str.len ] = '/'; memcpy(&es[0], srcdir->str.addr, srcdir->str.len); path_len += srcdir->str.len + tslash; es[ path_len ] = 0; } } flush_pio(); if (tt == io_std_device.in->type) resetterm(io_std_device.in); /* ignore interrupts */ sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = SIG_IGN; sigaction(SIGINT, &act, &intr); childid = fork(); /* BYPASSOK: we exec immediately, no FORK_CLEAN needed */ if (childid) { waitid = (int)childid; for (;;) { #ifdef _BSD WAIT(&wait_status, waitid); #else WAIT((int *)&status, waitid); #endif if (waitid == (int)childid) break; if (-1 == waitid) break; } if (-1 != waitid) dollar_zeditor = 0; else dollar_zeditor = errno; /* restore interrupt handler */ sigaction(SIGINT, &intr, 0); if (tt == io_std_device.in->type) setterm(io_std_device.in); } else { EXECL(editor.addr, editor.addr, es, 0); exit(-1); } }
/* * Main procedure. Process arguments and then * transfer control to the main command processing loop * in the routine commands. We are entered as either "ex", "edit" or "vi" * and the distinction is made here. Actually, we are "vi" if * there is a 'v' in our name, and "edit" if there is a 'd' in our * name. For edit we just diddle options; for vi we actually * force an early visual command, setting the external initev so * the q command in visual doesn't give command mode. */ int main(int ac, char **av) { #if 0 char *erpath = EXSTRINGS; #endif register char *cp; register int c; bool recov = 0; bool ivis = any('v', av[0]); bool itag = 0; bool fast = 0; #ifdef TRACE register char *tracef; #endif /* * Immediately grab the tty modes so that we wont * get messed up if an interrupt comes in quickly. */ gTTY(1); normf = tty; #if 0 /* * For debugging take files out of . if name is a.out. * If a 'd' in our name, then set options for edit. */ if (av[0][0] == 'a') erpath += 9; #endif if (ivis) { options[MAGIC].odefault = value(MAGIC) = 0; options[BEAUTIFY].odefault = value(BEAUTIFY) = 1; } else if (any('d', av[0])) { value(OPEN) = 0; value(REPORT) = 1; value(MAGIC) = 0; } /* * Open the error message file. */ draino(); #if 0 erfile = open(erpath, 0); if (erfile < 0) { flush(); exit(1); } #endif pstop(); /* * Initialize interrupt handling. */ oldhup = signal(SIGHUP, SIG_IGN); if (oldhup == SIG_DFL) signal(SIGHUP, onhup); oldquit = signal(SIGQUIT, SIG_IGN); ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL; if (signal(SIGTERM, SIG_IGN) == SIG_DFL) signal(SIGTERM, onhup); /* * Initialize end of core pointers. * Normally we avoid breaking back to fendcore after each * file since this can be expensive (much core-core copying). * If your system can scatter load processes you could do * this as ed does, saving a little core, but it will probably * not often make much difference. */ #ifdef UNIX_SBRK fendcore = (line *) sbrk(0); endcore = fendcore - 2; #else # define LINELIMIT 0x8000 fendcore = malloc(LINELIMIT * sizeof(line *)); endcore = fendcore + LINELIMIT - 1; #endif /* * Process flag arguments. */ ac--, av++; while (ac && av[0][0] == '-') { c = av[0][1]; if (c == 0) { hush = 1; value(AUTOPRINT) = 0; fast++; } else switch (c) { #ifdef TRACE case 'T': if (av[0][2] == 0) tracef = "trace"; else { tracef = tttrace; tracef[8] = av[0][2]; if (tracef[8]) tracef[9] = av[0][3]; else tracef[9] = 0; } trace = fopen(tracef, "w"); if (trace == NULL) ex_printf("Trace create error\n"); setbuf(trace, tracbuf); break; #endif #ifdef LISP case 'l': value(LISP) = 1; value(SHOWMATCH) = 1; break; #endif case 'r': recov++; break; case 't': if (ac > 1 && av[1][0] != '-') { ac--, av++; itag = 1; /* BUG: should check for too long tag. */ CP(lasttag, av[0]); } break; case 'v': globp = ""; ivis = 1; break; default: smerror("Unknown option %s\n", av[0]); break; } ac--, av++; } if (ac && av[0][0] == '+') { firstln = getn(av[0] + 1); if (firstln == 0) firstln = 20000; ac--, av++; } /* * If we are doing a recover and no filename * was given, then execute an exrecover command with * the -r option to type out the list of saved file names. * Otherwise set the remembered file name to the first argument * file name so the "recover" initial command will find it. */ if (recov) { if (ac == 0) { die++; setrupt(); execl(EXRECOVER, "exrecover", "-r", NULL); filioerr(EXRECOVER); exit(1); } CP(savedfile, *av); av++, ac--; } /* * Initialize the argument list. */ argv0 = av; argc0 = ac; args0 = av[0]; erewind(); /* * Initialize a temporary file (buffer) and * set up terminal environment. Read user startup commands. */ init(); if (setexit() == 0) { setrupt(); intty = isatty(0); if (fast || !intty) setterm("dumb"); else { gettmode(); if ((cp = getenv("TERM")) != 0) setterm(cp); if ((cp = getenv("HOME")) != 0) source(strcat(strcpy(genbuf, cp), "/.exrc"), 1); } } /* * Initial processing. Handle tag, recover, and file argument * implied next commands. If going in as 'vi', then don't do * anything, just set initev so we will do it later (from within * visual). */ if (setexit() == 0) { if (recov) globp = "recover"; else if (itag) globp = ivis ? "tag" : "tag|p"; else if (argc) globp = "next"; if (ivis) initev = globp; else if (globp) { inglobal = 1; commands(1, 1); inglobal = 0; } } /* * Vi command... go into visual. * Strange... everything in vi usually happens * before we ever "start". */ if (ivis) { /* * Don't have to be upward compatible with stupidity * of starting editing at line $. */ if (dol > zero) dot = one; globp = "visual"; if (setexit() == 0) commands(1, 1); } /* * Clear out trash in state accumulated by startup, * and then do the main command loop for a normal edit. * If you quit out of a 'vi' command by doing Q or ^\, * you also fall through to here. */ ungetchar(0); globp = 0; initev = 0; setlastchar('\n'); setexit(); commands(0, 0); cleanup(1); return 0; }
set() { register char *cp; register struct option *op; register int c; bool no; extern short ospeed; setnoaddr(); if (skipend()) { if (peekchar() != EOF) ignchar(); propts(); return; } do { cp = optname; do { if (cp < &optname[ONMSZ - 2]) *cp++ = getchar(); } while (isalnum(peekchar())); *cp = 0; cp = optname; if (eq("all", cp)) { if (inopen) pofix(); prall(); goto next; } no = 0; if (cp[0] == 'n' && cp[1] == 'o') { cp += 2; no++; } /* Implement w300, w1200, and w9600 specially */ if (eq(cp, "w300")) { if (ospeed >= B1200) { dontset: ignore(getchar()); /* = */ ignore(getnum()); /* value */ continue; } cp = "window"; } else if (eq(cp, "w1200")) { if (ospeed < B1200 || ospeed >= B2400) goto dontset; cp = "window"; } else if (eq(cp, "w9600")) { if (ospeed < B2400) goto dontset; cp = "window"; } for (op = options; op < &options[NOPTS]; op++) if (eq(op->oname, cp) || op->oabbrev && eq(op->oabbrev, cp)) break; if (op->oname == 0) serror("%s: No such option@- 'set all' gives all option values", cp); c = skipwh(); if (peekchar() == '?') { ignchar(); printone: propt(op); noonl(); goto next; } if (op->otype == ONOFF) { op->ovalue = 1 - no; if (op == &options[PROMPT]) oprompt = 1 - no; goto next; } if (no) serror("Option %s is not a toggle", op->oname); if (c != 0 || setend()) goto printone; if (getchar() != '=') serror("Missing =@in assignment to option %s", op->oname); switch (op->otype) { case NUMERIC: if (!isdigit(peekchar())) error("Digits required@after ="); op->ovalue = getnum(); if (value(TABSTOP) <= 0) value(TABSTOP) = TABS; if (op == &options[WINDOW]) { if (value(WINDOW) >= LINES) value(WINDOW) = LINES-1; vsetsiz(value(WINDOW)); } break; case STRING: case OTERM: cp = optname; while (!setend()) { if (cp >= &optname[ONMSZ]) error("String too long@in option assignment"); /* adb change: allow whitepace in strings */ if( (*cp = getchar()) == '\\') if( peekchar() != EOF) *cp = getchar(); cp++; } *cp = 0; if (op->otype == OTERM) { /* * At first glance it seems like we shouldn't care if the terminal type * is changed inside visual mode, as long as we assume the screen is * a mess and redraw it. However, it's a much harder problem than that. * If you happen to change from 1 crt to another that both have the same * size screen, it's OK. But if the screen size if different, the stuff * that gets initialized in vop() will be wrong. This could be overcome * by redoing the initialization, e.g. making the first 90% of vop into * a subroutine. However, the most useful case is where you forgot to do * a setenv before you went into the editor and it thinks you're on a dumb * terminal. Ex treats this like hardcopy and goes into HARDOPEN mode. * This loses because the first part of vop calls oop in this case. * The problem is so hard I gave up. I'm not saying it can't be done, * but I am saying it probably isn't worth the effort. */ if (inopen) error("Can't change type of terminal from within open/visual"); setterm(optname); } else { CP(op->osvalue, optname); op->odefault = 1; } break; } next: flush(); } while (!skipend()); eol(); }
void refresh(void) { static int inlist; /* avoiding recursion */ int canscroll = 0, /* number of lines we are allowed to scroll */ ln = 0, /* current line we're working on */ more_status = 0, /* more stuff in status line */ nvcs = 0, nvln = -1, /* video cursor column and line */ t0 = -1, /* tmp */ tosln = 0; /* tmp in statusline stuff */ unsigned char *s, /* pointer into the video buffer */ *t, /* pointer into the real buffer */ *sen, /* pointer to end of the video buffer (eol) */ *scs; /* pointer to cursor position in real buffer */ char **qbuf; /* tmp */ /* If this is called from listmatches() (indirectly via trashzle()), and * * that was called from the end of refresh(), then we don't need to do * * anything. All this `inlist' code is actually unnecessary, but it * * improves speed a little in a common case. */ if (inlist) return; #ifdef HAVE_SELECT cost = 0; /* reset */ #endif #ifndef WINNT /* Nov 96: <mason> I haven't checked how complete this is. sgtty stuff may or may not work */ oxtabs = ((SGTTYFLAG & SGTABTYPE) == SGTABTYPE); #else WINNT oxtabs = 0; #endif WINNT cleareol = 0; /* unset */ more_start = more_end = 0; /* unset */ if (isset(SINGLELINEZLE) || lines < 3 || (termflags & (TERM_NOUP | TERM_BAD | TERM_UNKNOWN))) termflags |= TERM_SHORT; else termflags &= ~TERM_SHORT; if (resetneeded) { onumscrolls = 0; setterm(); #if defined( TIOCGWINSZ) || defined(WINNT) if (winchanged) { moveto(0, 0); t0 = olnct; /* this is to clear extra lines even when */ winchanged = 0; /* the terminal cannot TCCLEAREOD */ } #endif resetvideo(); resetneeded = 0; /* unset */ oput_rpmpt = 0; /* no right-prompt currently on screen */ /* we probably should only have explicitly set attributes */ tsetcap(TCALLATTRSOFF, 0); tsetcap(TCSTANDOUTEND, 0); tsetcap(TCUNDERLINEEND, 0); if (!clearflag) if (tccan(TCCLEAREOD)) tcout(TCCLEAREOD); else cleareol = 1; /* request: clear to end of line */ if (t0 > -1) olnct = t0; if (termflags & TERM_SHORT) vcs = 0; else if (!clearflag && lpptlen) zwrite(lpptbuf, lpptlen, 1, shout); if (clearflag) { zputc('\r', shout); vcs = 0; moveto(0, pptw); } fflush(shout); clearf = clearflag; } else if (winw != columns || rwinh != lines) resetvideo(); /* now winw equals columns and winh equals lines width comparisons can be made with winw, height comparisons with winh */ if (termflags & TERM_SHORT) { singlerefresh(); return; } if (cs < 0) { #ifdef DEBUG fprintf(stderr, "BUG: negative cursor position\n"); fflush(stderr); #endif cs = 0; } scs = line + cs; numscrolls = 0; /* first, we generate the video line buffers so we know what to put on the screen - also determine final cursor position (nvln, nvcs) */ /* Deemed necessary by PWS 1995/05/15 due to kill-line problems */ if (!*nbuf) *nbuf = (char *)zalloc(winw + 2); s = (unsigned char *)(nbuf[ln = 0] + pptw); t = line; sen = (unsigned char *)(*nbuf + winw); for (; t < line+ll; t++) { if (t == scs) /* if cursor is here, remember it */ nvcs = s - (unsigned char *)(nbuf[nvln = ln]); if (*t == '\n') { /* newline */ nbuf[ln][winw + 1] = '\0'; /* text not wrapped */ nextline } else if (*t == '\t') { /* tab */
int main (int argc, char **argv) { srand (time (NULL)); int port = 8080; int work = 4; sighandleall (&signal_handler, SA_RESTART); argv0 = *argv; setname ("cws[master]"); int selfpiperead; { int pipefd[2]; if (pipe (pipefd) == -1) { die("pipe"); } selfpipe = pipefd[1]; selfpiperead = pipefd[0]; } worker_init (port, "file"); spawn_workers (work); tcgetattr (STDIN_FILENO, &old_term); atexit (&cleanup); setterm(); int epollfd = epoll(); epoll_add (epollfd, STDIN_FILENO); epoll_add (epollfd, selfpiperead); struct epoll_event events[MAX_QUEUE]; int i, n; char cmd; while (1) { n = epoll_wait (epollfd, events, MAX_QUEUE, -1); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { exit(1); } else if (STDIN_FILENO == events[i].data.fd) { // user input event cmd = getchar(); switch (cmd) { case 'k': printf ("Killing workers\n"); finish(1); break; case 'q': printf ("Telling workers to exit\n"); finish(0); break; case '+': spawn_workers (worker_count + 1); break; case '-': spawn_workers (worker_count - 1); break; } } else { // pipe event if (read (selfpiperead, &cmd, 1) <= 0) { die ("read"); } switch (cmd) { case CMD_KILL: printf ("Killing workers\n"); finish(0); break; case CMD_TERM: printf ("Telling workers to exit\n"); finish(1); break; case CMD_INCR: spawn_workers (worker_count + 1); break; case CMD_DECR: spawn_workers (worker_count - 1); break; case CMD_CHLD: check_workers(); break; } } } } return 0; }
short iott_open(io_log_name *dev_name, mval *pp, int fd, mval *mspace, int4 timeout) { unsigned char ch; d_tt_struct *tt_ptr; io_desc *ioptr; int status; int save_errno; int p_offset; error_def(ERR_NOTERMENV); error_def(ERR_NOTERMENTRY); error_def(ERR_NOTERMINFODB); error_def(ERR_TCGETATTR); ioptr = dev_name->iod; if (ioptr->state == dev_never_opened) { dev_name->iod->dev_sp = (void *)malloc(sizeof(d_tt_struct) + sizeof(struct termios)); memset(dev_name->iod->dev_sp, 0, sizeof(d_tt_struct) + sizeof(struct termios)); tt_ptr = (d_tt_struct *)dev_name->iod->dev_sp; tt_ptr->ttio_struct = (struct termios *)((char *)tt_ptr + sizeof(d_tt_struct)); tt_ptr->in_buf_sz = TTDEF_BUF_SZ; tt_ptr->enbld_outofbands.x = 0; tt_ptr->term_ctrl &= (~TRM_NOECHO); tt_ptr->mask_term.mask[0] = TERM_MSK; tt_ptr->ttybuff = (char *)malloc(IOTT_BUFF_LEN); } tt_ptr = (d_tt_struct *)dev_name->iod->dev_sp; p_offset = 0; while (*(pp->str.addr + p_offset) != iop_eol) { if ((ch = *(pp->str.addr + p_offset++)) == iop_exception) { ioptr->error_handler.len = *(pp->str.addr + p_offset); ioptr->error_handler.addr = (char *)(pp->str.addr + p_offset + 1); s2pool(&ioptr->error_handler); break; } else if (ch == iop_canonical) tt_ptr->canonical = TRUE; else if (ch == iop_nocanonical) tt_ptr->canonical = FALSE; p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } if (ioptr->state != dev_open) { int status; char *env_term; assert(fd >= 0); tt_ptr->fildes = fd; status = tcgetattr(tt_ptr->fildes, tt_ptr->ttio_struct); if (0 != status) { save_errno = errno; if (gtm_isanlp(tt_ptr->fildes) == 0) rts_error(VARLSTCNT(4) ERR_TCGETATTR, 1, tt_ptr->fildes, save_errno); } if (run_time) setterm(ioptr); status = getcaps(tt_ptr->fildes); if (1 != status) { if (status == 0) { env_term = GETENV("TERM"); if (!env_term) { rts_error(VARLSTCNT(1) ERR_NOTERMENV); env_term = "unknown"; } rts_error(VARLSTCNT(4) ERR_NOTERMENTRY, 2, LEN_AND_STR(env_term)); } else rts_error(VARLSTCNT(1) ERR_NOTERMINFODB); } ioptr->width = COLUMNS; ioptr->length = GTM_LINES; ioptr->wrap = (0 == AUTO_RIGHT_MARGIN) ? FALSE : TRUE; /* defensive programming; till we are absolutely, positively * certain that there are no uses of wrap == TRUE */ ioptr->state = dev_open; tt_ptr->tbuffp = tt_ptr->ttybuff; /* Buffer is now empty */ } return TRUE; }
/* * Main procedure. Process arguments and then * transfer control to the main command processing loop * in the routine commands. We are entered as either "ex", "edit", "vi" * or "view" and the distinction is made here. Actually, we are "vi" if * there is a 'v' in our name, "view" is there is a 'w', and "edit" if * there is a 'd' in our name. For edit we just diddle options; * for vi we actually force an early visual command. */ int main(int ac, char **av) { #ifndef VMUNIX char *erpath = EXSTRINGS; #endif register char *cp; register int c; bool recov = 0; bool ivis; bool itag = 0; bool fast = 0; #ifdef TRACE register char *tracef; #endif /* * Immediately grab the tty modes so that we wont * get messed up if an interrupt comes in quickly. */ gTTY(1); #ifndef USG3TTY normf = tty.sg_flags; #else normf = tty; #endif ppid = getpid(); /* * Defend against d's, v's, w's, and a's in directories of * path leading to our true name. */ av[0] = tailpath(av[0]); /* * Figure out how we were invoked: ex, edit, vi, view. */ ivis = any('v', av[0]); /* "vi" */ if (any('w', av[0])) /* "view" */ value(READONLY) = 1; if (any('d', av[0])) { /* "edit" */ value(OPEN) = 0; value(REPORT) = 1; value(MAGIC) = 0; } #ifndef VMUNIX /* * For debugging take files out of . if name is a.out. */ if (av[0][0] == 'a') erpath = tailpath(erpath); #endif /* * Open the error message file. */ draino(); #ifndef VMUNIX erfile = open(erpath+4, O_RDONLY); if (erfile < 0) { erfile = open(erpath, O_RDONLY); } #endif pstop(); /* * Initialize interrupt handling. */ oldhup = signal(SIGHUP, SIG_IGN); if (oldhup == SIG_DFL) signal(SIGHUP, onhup); oldquit = signal(SIGQUIT, SIG_IGN); ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL; if (signal(SIGTERM, SIG_IGN) == SIG_DFL) signal(SIGTERM, onhup); #ifdef SIGEMT if (signal(SIGEMT, SIG_IGN) == SIG_DFL) signal(SIGEMT, onemt); #endif /* * Initialize end of core pointers. * Normally we avoid breaking back to fendcore after each * file since this can be expensive (much core-core copying). * If your system can scatter load processes you could do * this as ed does, saving a little core, but it will probably * not often make much difference. */ #ifdef UNIX_SBRK fendcore = (line *) sbrk(0); endcore = fendcore - 2; #else # define LINELIMIT 0x8000 fendcore = malloc(LINELIMIT * sizeof(line *)); endcore = fendcore + LINELIMIT - 1; #endif /* * Process flag arguments. */ ac--, av++; while (ac && av[0][0] == '-') { c = av[0][1]; if (c == 0) { hush = 1; value(AUTOPRINT) = 0; fast++; } else switch (c) { case 'R': value(READONLY) = 1; break; #ifdef TRACE case 'T': if (av[0][2] == 0) tracef = "trace"; else { tracef = tttrace; tracef[8] = av[0][2]; if (tracef[8]) tracef[9] = av[0][3]; else tracef[9] = 0; } trace = fopen(tracef, "w"); if (trace == NULL) ex_printf("Trace create error\n"); setbuf(trace, tracbuf); break; #endif #ifdef LISPCODE case 'l': value(LISP) = 1; value(SHOWMATCH) = 1; break; #endif case 'r': recov++; break; case 't': if (ac > 1 && av[1][0] != '-') { ac--, av++; itag = 1; /* BUG: should check for too long tag. */ CP(lasttag, av[0]); } break; case 'v': ivis = 1; break; case 'w': defwind = 0; if (av[0][2] == 0) defwind = 3; else for (cp = &av[0][2]; isdigit((int)*cp); cp++) defwind = 10*defwind + *cp - '0'; break; #ifdef CRYPT case 'x': /* -x: encrypted mode */ xflag = 1; break; #endif default: smerror("Unknown option %s\n", av[0]); break; } ac--, av++; } #ifdef SIGTSTP if (!hush && signal(SIGTSTP, SIG_IGN) == SIG_DFL) signal(SIGTSTP, onsusp), dosusp++; #endif if (ac && av[0][0] == '+') { firstpat = &av[0][1]; ac--, av++; } #ifdef CRYPT if(xflag){ key = getpass(KEYPROMPT); kflag = crinit(key, perm); } #endif /* * If we are doing a recover and no filename * was given, then execute an exrecover command with * the -r option to type out the list of saved file names. * Otherwise set the remembered file name to the first argument * file name so the "recover" initial command will find it. */ if (recov) { if (ac == 0) { ppid = 0; setrupt(); execl(EXRECOVER, "exrecover", "-r", NULL); filioerr(EXRECOVER); ex_exit(1); } CP(savedfile, *av); av++, ac--; } /* * Initialize the argument list. */ argv0 = av; argc0 = ac; args0 = av[0]; erewind(); /* * Initialize a temporary file (buffer) and * set up terminal environment. Read user startup commands. */ if (setexit() == 0) { setrupt(); intty = isatty(0); value(PROMPT) = intty; if ((cp = getenv("SHELL"))) CP(shell, cp); if (fast || !intty) setterm("dumb"); else { gettmode(); if ((cp = getenv("TERM")) != 0 && *cp) setterm(cp); } } if (setexit() == 0 && !fast && intty) { if ((globp = getenv("EXINIT")) && *globp) commands(1,1); else { globp = 0; if ((cp = getenv("HOME")) != 0 && *cp) source(strcat(strcpy(genbuf, cp), "/.exrc"), 1); } } init(); /* moved after prev 2 chunks to fix directory option */ /* * Initial processing. Handle tag, recover, and file argument * implied next commands. If going in as 'vi', then don't do * anything, just set initev so we will do it later (from within * visual). */ if (setexit() == 0) { if (recov) globp = "recover"; else if (itag) globp = ivis ? "tag" : "tag|p"; else if (argc) globp = "next"; if (ivis) initev = globp; else if (globp) { inglobal = 1; commands(1, 1); inglobal = 0; } } /* * Vi command... go into visual. * Strange... everything in vi usually happens * before we ever "start". */ if (ivis) { /* * Don't have to be upward compatible with stupidity * of starting editing at line $. */ if (dol > zero) dot = one; globp = "visual"; if (setexit() == 0) commands(1, 1); } /* * Clear out trash in state accumulated by startup, * and then do the main command loop for a normal edit. * If you quit out of a 'vi' command by doing Q or ^\, * you also fall through to here. */ seenprompt = 1; ungetchar(0); globp = 0; initev = 0; setlastchar('\n'); setexit(); commands(0, 0); cleanup(1); return 0; }