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

📄 dshell.c

📁 linux——shell nachos 的课程设计 第一个
💻 C
字号:
#include <sys/types.h>#include <sys/stat.h>#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <stdlib.h>#include <errno.h>/*命令行数据结构*/typedef struct tagCommand{	char **argv;//参数	int argc;//文件名(命令)}COMD;void processComd(COMD* pC, char* pBuf){	char *pchr = NULL;	char *pBegin = pBuf;	int n=1;	while ((pchr=strchr(pBegin, ' '))!=NULL)	{		pBegin=pchr+1;		while ((*pBegin)==' ')			pBegin++;		n++;	}	pC->argv=(char**)malloc(sizeof(char*)*(n+1));	pchr=NULL;	pBegin=pBuf;	int num=0;	while ((pchr=strchr(pBegin, ' '))!=NULL)	{		pC->argv[num]=(char*)malloc(sizeof(char)*(pchr-pBegin+1));		strncpy(pC->argv[num], pBegin, pchr-pBegin);		(pC->argv[num])[pchr-pBegin]='\0';		pBegin=pchr+1;		while ((*pBegin)==' ')			pBegin++;		num++;	}	pC->argv[num]=(char*)malloc(sizeof(char)*strlen(pBegin));	strcpy(pC->argv[num], pBegin);	num++;	pC->argv[num]=NULL;	pC->argc=num;}void findExec(COMD* pC, char* pBuf){		char *pchr = NULL;	char *paths = getenv("PATH");	char *pBegin = paths;	char **pDirs = NULL;	if ((pC->argv[0])[0]=='.' || (pC->argv[0])[0]=='/')	{		strcpy(pBuf, pC->argv[0]);		return;	}		int n=1;	while ((pchr=strchr(pBegin, ':'))!=NULL)	{		pBegin=pchr+1;		n++;	}	pDirs=(char**)malloc(sizeof(char*)*n);	pchr=NULL;	pBegin=paths;	int num=0;	while ((pchr=strchr(pBegin, ':'))!=NULL)	{		pDirs[num]=(char*)malloc(sizeof(char)*(pchr-pBegin+1));		strncpy(pDirs[num], pBegin, pchr-pBegin);		(pDirs[num])[pchr-pBegin]='\0';		pBegin=pchr+1;		num++;	}	pDirs[num]=(char*)malloc(sizeof(char)*strlen(pBegin));	strcpy(pDirs[num], pBegin);	num++;	int i=0;	for (i=0; i<num; i++)	{		strcpy(pBuf, pDirs[i]);		if ((pDirs[i])[strlen(pDirs[i])-1]!='/')			strcat(pBuf, "/");		strcat(pBuf, pC->argv[0]);		if (access(pBuf, F_OK)==0)		{			for (n=0; n<num; n++)			{				free(pDirs[n]);				pDirs[n]=NULL;			}			free(pDirs);			pDirs=NULL;			return;		}	}	for (n=0; n<num; n++)	{		free(pDirs[n]);		pDirs[n]=NULL;	}	free(pDirs);	pDirs=NULL;	pBuf[0]='\0';}int isBackground(COMD* pC){	if ((pC->argv[pC->argc-1])[strlen(pC->argv[pC->argc-1])-1]=='&')	{		if (strlen(pC->argv[pC->argc-1])-1==0)		{			free(pC->argv[pC->argc-1]);			pC->argv[pC->argc-1]=NULL;			pC->argc--;		}		else			(pC->argv[pC->argc-1])[strlen(pC->argv[pC->argc-1])-1]='\0';		return 1;	}	return 0;}void redirectInOut(COMD* pC, int* piid){	int i=0;	int j=0;	for (i=0; i<pC->argc; i++)	{		if (pC->argv[i]!=NULL && (pC->argv[i])[0]=='<')		{			/*redirect stdin*/			int fid;			char rname[100];			if ((pC->argv[i])[1]=='\0')			{				strcpy(rname, pC->argv[i+1]);				fid = open(rname, O_RDONLY);				if (fid==-1)				{					printf("Error opening input file!\n");					exit(2);				}				close(0);				dup(fid);				close(fid);				(pC->argv[i])[0]='\0';				(pC->argv[i+1])[0]='\0';				free(pC->argv[i]);				pC->argv[i]=NULL;				free(pC->argv[i+1]);				pC->argv[i+1]=NULL;			}			else				if ((pC->argv[i])[1]=='/' && (pC->argv[i])[2]=='\0')				{					close(0);					dup(piid[0]);					close(piid[1]);					(pC->argv[i])[0]='\0';					free(pC->argv[i]);					pC->argv[i]=NULL;				}				else				{					strcpy(rname, (pC->argv[i])+1);					fid = open(rname, O_RDONLY);					if (fid==-1)					{						printf("Error opening input file!\n");						exit(2);					}					close(0);					dup(fid);					close(fid);					(pC->argv[i])[0]='\0';					free(pC->argv[i]);					pC->argv[i]=NULL;				}		}		if (pC->argv[i]!=NULL && (pC->argv[i])[0]=='>')		{			/*redirect stdout*/			int fid;			char rname[100];			if ((pC->argv[i])[1]=='\0')			{				strcpy(rname, pC->argv[i+1]);				fid = open(rname, O_WRONLY | O_CREAT);				if (fid==-1)				{					printf("Error accessing output file!\n");					exit(2);				}				close(1);				dup(fid);				close(fid);				(pC->argv[i])[0]='\0';				(pC->argv[i+1])[0]='\0';				free(pC->argv[i]);				pC->argv[i]=NULL;				free(pC->argv[i+1]);				pC->argv[i+1]=NULL;			}			else				if ((pC->argv[i])[1]=='/' && (pC->argv[i])[2]=='\0')				{					close(1);					dup(piid[1]);					close(piid[0]);					(pC->argv[i])[0]='\0';					free(pC->argv[i]);					pC->argv[i]=NULL;				}				else				{					strcpy(rname, (pC->argv[i])+1);					fid = open(rname, O_WRONLY | O_CREAT);					if (fid==-1)					{						printf("Error accessing output file!\n");						exit(2);					}					close(1);					dup(fid);					close(fid);					(pC->argv[i])[0]='\0';					free(pC->argv[i]);					pC->argv[i]=NULL;				}		}	}	for (i=0; i<pC->argc; i++)	{		int move=0;		for (j=0; j<pC->argc; j++)		{			if ((pC->argv[j])==NULL)			{				pC->argv[j]=pC->argv[j+1];				move=1;			}			if (move)			{				pC->argv[j]=pC->argv[j+1];			}		}	}}int* pipeInOut(COMD* pC){	int i=0;	int* pipeid = NULL;	for (i=0; i<pC->argc; i++)	{		if (((pC->argv[i])[0]=='<' || (pC->argv[i])[0]=='>') && (pC->argv[i])[1]=='/')		{			/*create pipe*/			pipeid = (int*)malloc(2*sizeof(int));			if (pipe(pipeid) == -1)			{				printf("Pipe creation error!\n");				exit(3);			}		}	}	return pipeid;}char* procPipe(char* pBuf){	char *pSecProc = NULL;	char *pchr = NULL;	if ((pchr=strchr(pBuf, '|'))!=NULL)	{		pchr--;		while ((*pchr)==' ')			pchr--;		pchr++;		(*pchr)='\0';		pchr++;		while ((*pchr)==' ')			pchr++;		if ((*pchr)=='|')			pchr++;		while ((*pchr)==' ')			pchr++;		pSecProc=(char*)malloc(sizeof(char)*1024);		strcpy(pSecProc, pchr);	}	return pSecProc;}int main(int argc, char *argv[], char *env[]){	printf ("Shell by llr, type \"exit\" return to bash.\n");	COMD execmd;	COMD* pSecCom = NULL;	execmd.argv=NULL;	execmd.argc=0;	char buf[1024],tmp;	char *pSecP = NULL;	do	{		if (execmd.argv!=NULL)		{			for (; execmd.argc>0; execmd.argc--)			{				free(execmd.argv[execmd.argc-1]);				execmd.argv[execmd.argc-1]=NULL;			}			free(execmd.argv);			execmd.argv=NULL;		}		printf("DShell>");		int i=0;		while((tmp=getchar())!='\n')		{			buf[i]=tmp;			i++;		}		buf[i]='\0';		pSecP = procPipe(buf);		if (pSecP!=NULL)		{			char *ad=" >/";			strcat(buf, ad);			char *ad2=" </";			strcat(pSecP, ad2);		}		processComd(&execmd, buf);		if (i==0)			continue;		findExec(&execmd, buf);		int bg=isBackground(&execmd);		if (pSecP!=NULL)		{			pSecCom = (COMD*)malloc(sizeof(COMD));			pSecCom->argv=NULL;			pSecCom->argc=0;			processComd(pSecCom, pSecP);			findExec(pSecCom, pSecP);			bg=isBackground(pSecCom);		}				int* pipeID = NULL;		if (strcmp(execmd.argv[0], "exit")!=0)		{			if (strcmp(buf, "")==0)			{				printf("Bad command or file name.\n");				continue;			}			/*ready to execute*/			int npid;			pipeID = pipeInOut(&execmd);			if ((npid=fork())==0)			{				errno=0;				redirectInOut(&execmd, pipeID);				int status = execve(buf, execmd.argv, env);				printf("Error executing specified file. (#%d)\n", errno);				return 1;			}			else			{				if (pSecP==NULL)				{					if (!bg)					{						int status;						wait(&status);					}					else					{						printf("Program ID#%d executed successful at background.\n", npid);					}				}			}			if (pSecP!=NULL)			{				if ((npid=fork())==0)				{					errno=0;					/*redirect to pipe*/					redirectInOut(pSecCom, pipeID);					int status = execve(pSecP, pSecCom->argv, env);					printf("Error executing specified file. (#%d)\n", errno);					return 1;				}				else				{					close(pipeID[0]);					close(pipeID[1]);					if (!bg)					{						int status;						wait(&status);					}					else					{						printf("Program ID#%d executed successful at background.\n", npid);					}				}			}		}		if (pSecP!=NULL)		{			sleep(1);			free(pipeID);			pipeID=NULL;			free(pSecP);			pSecP=NULL;			free(pSecCom);			pSecCom=NULL;		}	}while(strcmp(execmd.argv[0], "exit")!=0);		if (execmd.argv!=NULL)	{		for (; execmd.argc>0; execmd.argc--)		{			free(execmd.argv[execmd.argc-1]);			execmd.argv[execmd.argc-1]=NULL;		}		free(execmd.argv);		execmd.argv=NULL;	}	printf("Bye!\n");	return 0;}

⌨️ 快捷键说明

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