📄 dshell.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 + -