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

📄 shell.c

📁 TCP-IP红宝书源代码
💻 C
字号:
/* shell.c - shell */

#include <conf.h>
#include <kernel.h>
#include <proc.h>
#include <shell.h>
#include <cmd.h>
#include <tty.h>
#include <network.h>

struct	shvars	Shl;			/* globals used by Xinu shell	*/
struct	cmdent	cmds[]  = {CMDS};	/* shell commands		*/
LOCAL	char	errhd[] = "Syntax error\n";/* global error messages	*/
LOCAL	char	fmt[]   = "Cannot open %s\n";
LOCAL	char	fmt2[]  = "[%d]\n";

/*------------------------------------------------------------------------
 *  shell  -  Xinu shell with file redirection and background processing
 *------------------------------------------------------------------------
 */
shell(int dev)
{
	int	ntokens;
	int	i, j, len;
	int	com;
	char	*outnam, *innam, *index();
	int	stdin, stdout, stderr;
	Bool	backgnd;
	char	ch, mach[SHMLEN], *pch;
	int	child;

	Shl.shncmds = sizeof(cmds)/sizeof(struct cmdent);

	getname(mach);
	if (pch = index(mach, '.'))
		*pch = NULLCH;
	
	while (TRUE) {
		fprintf(dev, "%s %% ", mach);
		getutim(&Shl.shlast);
		if ( (len = read(dev, Shl.shbuf, SHBUFLEN)) == 0)
			len = read(dev, Shl.shbuf, SHBUFLEN);
		if (len == EOF)
			break;
		Shl.shbuf[len-1] = NULLCH;
		if ( (ntokens=lexan(Shl.shbuf)) == SYSERR) {
			fprintf(dev, errhd);
			continue;
		} else if (ntokens == 0)
			continue;
		outnam = innam = NULL;
		backgnd = FALSE;

		/* handle '&' */

		if (Shl.shtktyp[ntokens-1] == '&') {
			ntokens-- ;
			backgnd = TRUE;
		}

		/* scan tokens, accumulating length;  handling redirect	*/

		for (len=0,i=0 ; i<ntokens ; ) {
			if ((ch = Shl.shtktyp[i]) == '&') {
				ntokens = -1;
				break;
			} else if (ch == '>') {
				if (outnam != NULL || i >= --ntokens) {
					ntokens = -1;
					break;
				}
				outnam = Shl.shtok[i+1];
				for (ntokens--,j=i ; j<ntokens ; j++) {
					Shl.shtktyp[j] = Shl.shtktyp[j+2];
					Shl.shtok  [j] = Shl.shtok  [j+2];
				}
				continue;
			} else if (ch == '<') {
				if (innam != NULL || i >= --ntokens) {
					ntokens = -1;
					break;
				}
				innam = Shl.shtok[i+1];
				for (ntokens--,j=i ; j < ntokens ; j++) {
					Shl.shtktyp[j] = Shl.shtktyp[j+2];
					Shl.shtok  [j] = Shl.shtok  [j+2];
				}
				continue;
			} else {
				 len += strlen(Shl.shtok[i++]);
			}
		}
		if (ntokens <= 0) {
			fprintf(dev, errhd);
			continue;
		}
		stdin = stdout = stderr = dev;

		/* Look up command in table */

		for (com=0 ; com<Shl.shncmds ; com++) {
			if (strcmp(cmds[com].cmdnam,Shl.shtok[0]) == 0)
				break;
		}
		if (com >= Shl.shncmds) {
			fprintf(dev, "%s: not found\n", Shl.shtok[0]);
			continue;
		}

		/* handle built-in commands with procedure call */

		if (cmds[com].cbuiltin) {
			if (innam != NULL || outnam != NULL || backgnd)
				fprintf(dev, errhd);
			else if ( (*cmds[com].cproc)(stdin, stdout,
				stderr, ntokens, Shl.shtok) == SHEXIT)
				break;
			continue;
		}

		/* Open files and redirect I/O if specified */

		if (innam != NULL && (stdin=open(NAMESPACE,innam,"ro"))
			== SYSERR) {
			fprintf(dev, fmt, innam);
			continue;
		}
		if (outnam != NULL && (stdout=open(NAMESPACE,outnam,"w"))
			== SYSERR) {
			fprintf(dev, fmt, outnam);
			continue;
		}

		/* compute space needed for string args. (in bytes) */

		/* add a null for the end of each string, plus a    */
		/*    pointer to the string (see xinu2, p300)       */
		len += ntokens * (sizeof(char *) + sizeof(char));

		/* plus a (char *) null for the end of the table    */
		len += sizeof(char *);

		/* plus a pointer to the head of the table          */
		len += sizeof(char *);

		
		len = (len+3) & ~(unsigned) 0x3;

		control(dev, TTC_CPID, getpid());

		/* create process to execute conventional command */

		if ( (child = create(cmds[com].cproc, SHCMDSTK, SHCMDPRI,
				Shl.shtok[0],(len/sizeof(long)) + 4,
				stdin, stdout, stderr, ntokens))
				== SYSERR) {
			fprintf(dev, "Cannot create\n");
			close(stdout);
			close(stdin);
			continue;
		}
		addarg(child, ntokens, len);
		setdev(child, stdin, stdout);
		if (backgnd) {
			fprintf(dev, fmt2, child);
			resume(child);
		} else {
			setnok(getpid(), child);
			recvclr();
			resume(child);
			if (receive() == INTRMSG) {
				setnok(BADPID, child);
				fprintf(dev, fmt2, child);
			}
		}
	}
	return(OK);
}

⌨️ 快捷键说明

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