⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csh.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
}Char   *jobargv[2] = {STRjobs, 0};/* * Catch an interrupt, e.g. during lexical input. * If we are an interactive shell, we reset the interrupt catch * immediately.  In any case we drain the shell output, * and finally go through the normal error mechanism, which * gets a chance to make the shell go away. *//* ARGSUSED */voidpintr(notused)	int notused;{    pintr1(1);}voidpintr1(wantnl)    bool    wantnl;{    Char **v;    sigset_t omask;    omask = sigblock((sigset_t) 0);    if (setintr) {	(void) sigsetmask(omask & ~sigmask(SIGINT));	if (pjobs) {	    pjobs = 0;	    (void) fprintf(cshout, "\n");	    dojobs(jobargv, NULL);	    stderror(ERR_NAME | ERR_INTR);	}    }    (void) sigsetmask(omask & ~sigmask(SIGCHLD));    (void) fpurge(cshout);    (void) endpwent();    /*     * If we have an active "onintr" then we search for the label. Note that if     * one does "onintr -" then we shan't be interruptible so we needn't worry     * about that here.     */    if (gointr) {	gotolab(gointr);	timflg = 0;	if ((v = pargv) != NULL)	    pargv = 0, blkfree(v);	if ((v = gargv) != NULL)	    gargv = 0, blkfree(v);	reset();    }    else if (intty && wantnl) {	(void) fputc('\r', cshout);	(void) fputc('\n', cshout);    }    stderror(ERR_SILENT);}/* * Process is the main driving routine for the shell. * It runs all command processing, except for those within { ... } * in expressions (which is run by a routine evalav in sh.exp.c which * is a stripped down process), and `...` evaluation which is run * also by a subset of this code in sh.glob.c in the routine backeval. * * The code here is a little strange because part of it is interruptible * and hence freeing of structures appears to occur when none is necessary * if this is ignored. * * Note that if catch is not set then we will unwind on any error. * If an end-of-file occurs, we return. */static struct command *savet = NULL;voidprocess(catch)    bool    catch;{    jmp_buf osetexit;    struct command *t = savet;    savet = NULL;    getexit(osetexit);    for (;;) {	pendjob();	paraml.next = paraml.prev = &paraml;	paraml.word = STRNULL;	(void) setexit();	justpr = enterhist;	/* execute if not entering history */	/*	 * Interruptible during interactive reads	 */	if (setintr)	    (void) sigsetmask(sigblock((sigset_t) 0) & ~sigmask(SIGINT));	/*	 * For the sake of reset()	 */	freelex(&paraml);	if (savet)	    freesyn(savet), savet = NULL;	if (haderr) {	    if (!catch) {		/* unwind */		doneinp = 0;		resexit(osetexit);		savet = t;		reset();	    }	    haderr = 0;	    /*	     * Every error is eventually caught here or the shell dies.  It is	     * at this point that we clean up any left-over open files, by	     * closing all but a fixed number of pre-defined files.  Thus	     * routines don't have to worry about leaving files open due to	     * deeper errors... they will get closed here.	     */	    closem();	    continue;	}	if (doneinp) {	    doneinp = 0;	    break;	}	if (chkstop)	    chkstop--;	if (neednote)	    pnote();	if (intty && prompt && evalvec == 0) {	    mailchk();	    /*	     * If we are at the end of the input buffer then we are going to	     * read fresh stuff. Otherwise, we are rereading input and don't	     * need or want to prompt.	     */	    if (aret == F_SEEK && fseekp == feobp)		printprompt();	    (void) fflush(cshout);	}	if (seterr) {	    xfree((ptr_t) seterr);	    seterr = NULL;	}	/*	 * Echo not only on VERBOSE, but also with history expansion. If there	 * is a lexical error then we forego history echo.	 */	if ((lex(&paraml) && !seterr && intty) || adrof(STRverbose)) {	    prlex(csherr, &paraml);	}	/*	 * The parser may lose space if interrupted.	 */	if (setintr)	    (void) sigblock(sigmask(SIGINT));	/*	 * Save input text on the history list if reading in old history, or it	 * is from the terminal at the top level and not in a loop.	 *	 * PWP: entry of items in the history list while in a while loop is done	 * elsewhere...	 */	if (enterhist || (catch && intty && !whyles))	    savehist(&paraml);	/*	 * Print lexical error messages, except when sourcing history lists.	 */	if (!enterhist && seterr)	    stderror(ERR_OLD);	/*	 * If had a history command :p modifier then this is as far as we	 * should go	 */	if (justpr)	    reset();	alias(&paraml);	/*	 * Parse the words of the input into a parse tree.	 */	savet = syntax(paraml.next, &paraml, 0);	if (seterr)	    stderror(ERR_OLD);	execute(savet, (tpgrp > 0 ? tpgrp : -1), NULL, NULL);	/*	 * Made it!	 */	freelex(&paraml);	freesyn((struct command *) savet), savet = NULL;    }    resexit(osetexit);    savet = t;}void/*ARGSUSED*/dosource(v, t)    Char **v;    struct command *t;{    register Char *f;    bool    hflg = 0;    Char    buf[BUFSIZ];    v++;    if (*v && eq(*v, STRmh)) {	if (*++v == NULL)	    stderror(ERR_NAME | ERR_HFLAG);	hflg++;    }    (void) Strcpy(buf, *v);    f = globone(buf, G_ERROR);    (void) strcpy((char *) buf, short2str(f));    xfree((ptr_t) f);    if (!srcfile((char *) buf, 0, hflg) && !hflg)	stderror(ERR_SYSTEM, (char *) buf, strerror(errno));}/* * Check for mail. * If we are a login shell, then we don't want to tell * about any mail file unless its been modified * after the time we started. * This prevents us from telling the user things he already * knows, since the login program insists on saying * "You have mail." */static voidmailchk(){    register struct varent *v;    register Char **vp;    time_t  t;    int     intvl, cnt;    struct stat stb;    bool    new;    v = adrof(STRmail);    if (v == 0)	return;    (void) time(&t);    vp = v->vec;    cnt = blklen(vp);    intvl = (cnt && number(*vp)) ? (--cnt, getn(*vp++)) : MAILINTVL;    if (intvl < 1)	intvl = 1;    if (chktim + intvl > t)	return;    for (; *vp; vp++) {	if (stat(short2str(*vp), &stb) < 0)	    continue;	new = stb.st_mtime > time0.tv_sec;	if (stb.st_size == 0 || stb.st_atime > stb.st_mtime ||	    (stb.st_atime < chktim && stb.st_mtime < chktim) ||	    (loginsh && !new))	    continue;	if (cnt == 1)	    (void) fprintf(cshout, "You have %smail.\n", new ? "new " : "");	else	    (void) fprintf(cshout, "%s in %s.\n", new ? "New mail" : "Mail",			   vis_str(*vp));    }    chktim = t;}/* * Extract a home directory from the password file * The argument points to a buffer where the name of the * user whose home directory is sought is currently. * We write the home directory of the user back there. */intgethdir(home)    Char   *home;{    Char   *h;    struct passwd *pw;    /*     * Is it us?     */    if (*home == '\0') {	if ((h = value(STRhome)) != NULL) {	    (void) Strcpy(home, h);	    return 0;	}	else	    return 1;    }    if ((pw = getpwnam(short2str(home))) != NULL) {	(void) Strcpy(home, str2short(pw->pw_dir));	return 0;    }    else	return 1;}/* * When didfds is set, we do I/O from 0, 1, 2 otherwise from 15, 16, 17 * We also check if the shell has already changed the decriptor to point to * 0, 1, 2 when didfds is set. */#define DESC(a) (*((int *) (a)) - (didfds && *((int *) a) >= FSHIN ? FSHIN : 0))static intreadf(oreo, buf, siz)    void *oreo;    char *buf;    int siz;{    return read(DESC(oreo), buf, siz);}static intwritef(oreo, buf, siz)    void *oreo;    const char *buf;    int siz;{    return write(DESC(oreo), buf, siz);}static fpos_tseekf(oreo, off, whence)    void *oreo;    fpos_t off;    int whence;{    return lseek(DESC(oreo), off, whence);}static intclosef(oreo)    void *oreo;{    return close(DESC(oreo));}/* * Print the visible version of a string. */intvis_fputc(ch, fp)    int ch;    FILE *fp;{    char uenc[5];	/* 4 + NULL */    if (ch & QUOTE) 	return fputc(ch & TRIM, fp);    /*      * XXX: When we are in AsciiOnly we want all characters >= 0200 to     * be encoded, but currently there is no way in vis to do that.     */    (void) vis(uenc, ch & TRIM, VIS_NOSLASH, 0);    return fputs(uenc, fp);}/* * Move the initial descriptors to their eventual * resting places, closin all other units. */voidinitdesc(){    didfds = 0;			/* 0, 1, 2 aren't set up */    (void) ioctl(SHIN = dcopy(0, FSHIN), FIOCLEX, NULL);    (void) ioctl(SHOUT = dcopy(1, FSHOUT), FIOCLEX, NULL);    (void) ioctl(SHERR = dcopy(2, FSHERR), FIOCLEX, NULL);    (void) ioctl(OLDSTD = dcopy(SHIN, FOLDSTD), FIOCLEX, NULL);    closem();}void#ifdef PROFdone(i)#elsexexit(i)#endif    int     i;{    untty();    _exit(i);}static Char **defaultpath(){    char   *ptr;    Char  **blk, **blkp;    struct stat stb;    blkp = blk = (Char **) xmalloc((size_t) sizeof(Char *) * 10);#define DIRAPPEND(a)  \	if (stat(ptr = a, &stb) == 0 && (stb.st_mode & S_IFMT) == S_IFDIR) \		*blkp++ = SAVE(ptr)    DIRAPPEND(_PATH_BIN);    DIRAPPEND(_PATH_USRBIN);#undef DIRAPPEND    if (euid != 0 && uid != 0)	*blkp++ = Strsave(STRdot);    *blkp = NULL;    return (blk);}voidprintprompt(){    register Char *cp;    if (!whyles) {	for (cp = value(STRprompt); *cp; cp++)	    if (*cp == HIST)		(void) fprintf(cshout, "%d", eventno + 1);	    else {		if (*cp == '\\' && cp[1] == HIST)		    cp++;		(void) vis_fputc(*cp | QUOTE, cshout);	    }    }    else	/*	 * Prompt for forward reading loop body content.	 */	(void) fprintf(cshout, "? ");    (void) fflush(cshout);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -