?? test14_2.txt
字號(hào):
/* 頭文件head.h*/
#include <stdio.h>
#include <limits.h>
#include <signal.h>
#include <fcntl.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define MAXINPUTLN 120
/*輸出行的最大長(zhǎng)度*/
#define MAXARG 15
/*一個(gè)簡(jiǎn)單命令的最大數(shù)目*/
#define PIPELINE 5
/*一個(gè)管道的最大簡(jiǎn)單命令數(shù)*/
#define MAXNAME 100
/*I/O重定向文件名字的最大長(zhǎng)度*/
char inputln[MAXINPUTLN+1];
/*用戶的輸入 */
char *inputlnptr;
/* 指向當(dāng)前inputln[ ]數(shù)組的當(dāng)前位置*/
char avline[MAXINPUTLN+1];
/*從inputln[ ]數(shù)組中提取出來(lái)的參數(shù)字符串 */
char *avptr;
/*指向avline[]數(shù)組中的當(dāng)前位置*/
char infile[MAXINPUTLN+1];
/* 輸入重定向文件的名字*/
char outfile[MAXNAME+1];
/*輸出重定向文件的名字*/
int background;
/*為TRUE時(shí)為后臺(tái)命令(命令行以&結(jié)尾,否則為前臺(tái),*/
int lastpid;
/*管道中最后一條簡(jiǎn)單命令的進(jìn)程標(biāo)識(shí)*/
int append;
/*如果為TRUE表示命令結(jié)尾用>>來(lái)說(shuō)明附加在某文件末尾*/
struct cmd
{
char *av[MAXARG];
/*存放命令和參數(shù)的一維數(shù)組*/
int infd;
int outfd;
}cmdlin[PIPELINE];
/*一個(gè)簡(jiǎn)單命令結(jié)構(gòu)*/
/*主過(guò)程main.c*/
//#include "head.h"
main(void)
{
int j;
init_once( );
/*對(duì)程序進(jìn)行初始化*/
for(;;)
{
init_command( );
/*每執(zhí)行一條命令都要進(jìn)行一次初始化*/
if(get_comln( ))
/*得到命令行輸入*/
if(j=get_simcom())
/*分析出簡(jiǎn)單命令的個(gè)數(shù)*/
execute(j);
/*執(zhí)行這j個(gè)命令*/
}
}
/*初始化文件init.c*/
init_once(void)
{
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
}
init_command(void)
/*每次輸入命令都要進(jìn)行初始化*/
{
int k;
background=FALSE;
inputlnptr=inputln;
avptr=avline;
infile[0]= '\0';
outfile[0]= '\0';
append=FALSE;
for(k=0;k<OPEN_MAX;++k)
{
cmdlin[k].infd=0;
cmdlin[k].outfd=1;
}
for(k=3;k<OPEN_MAX;++k)
close(k);
printf("tsh:");
fflush(stdout);
}
/*語(yǔ)法分析文件get_simcom.c*/
get_simcom(void)
{
int m;
get_simarg(0);
/*先分析第一條簡(jiǎn)單命令*/
if(check( "<"))
/*如果有輸入文件,就記錄輸入文件名*/
get_word(infile);
/*下面是循環(huán)分析管道中的每一條簡(jiǎn)單命令*/
for(m=1;m<PIPELINE;++m)
{
if(check("|"))
get_simarg(m);
else
break;
}
/*如果有輸出文件,記錄輸出文件名*/
if(check( ">"))
{
if(check( ">"))
/*輸出到某文件的末尾*/
append=TRUE;
get_word(outfile);
}
/*后臺(tái)運(yùn)行命令*/
if(check( "&"))
background=TRUE;
/*下面代碼分析完整個(gè)命令,返回簡(jiǎn)單命令個(gè)數(shù)*/
if(check( "\n"))
return(m);
else
/*如果沒(méi)分析完畢,說(shuō)明輸入的命令行有語(yǔ)法錯(cuò)誤*/
{
fprintf(stderr, "Command line syntax error\n");
return(ERROR);
}
}
/*得到下一個(gè)標(biāo)識(shí)符get_word.c*/
get_word(char *name)
{
int m;
/*從inputln[]中得到一個(gè)單詞,也就是一個(gè)標(biāo)識(shí)符*/
for(m=0;m<MAXNAME;++m)
{
switch(*inputlnptr)
{
case ' ':
case '|':
case '>':
case '\n':
case '<':
case '&':
case '\t':
*name='\0';
return;
default:
name=inputlnptr++;
name++;
}
}
*name= '\0';
}
/*得到當(dāng)前命令行g(shù)et_comin.c*/
get_comln(void)
{
int m;
for(m=0;(inputln[m]=getchar( ))!= '\n'&& m<MAXINPUTLN;++m);
if(m==MAXINPUTLN)
/*如果輸入的命令超過(guò)了最大長(zhǎng)度,就報(bào)錯(cuò)*/
{
fprintf(stderr, "Command line too long\n");
return(ERROR);
}
inputln[m+1]='\0';
return(OK);
}
/*執(zhí)行簡(jiǎn)單命令run_com.c*/
run_com(struct cmd *ptr)
{
int k,pid;
if(pid=fork( ))
/*父進(jìn)程*/
{
if(background==TRUE)
printf( "%d\n",pid);
/*如果是后臺(tái)命令,打印出進(jìn)程標(biāo)識(shí)*/
lastpid=pid;
/*記錄最后一個(gè)簡(jiǎn)單命令的進(jìn)程標(biāo)志*/
}
else
{
/*如果是后臺(tái)進(jìn)程要關(guān)閉鍵盤輸入*/
if(ptr->infd==0&&background==TRUE)
ptr->infd=open( "/dev/null",O_RDONLY);
/*對(duì)輸入進(jìn)行重定向*/
if(ptr->infd!=0)
{
close(0);
dup(ptr->infd);
}
/*對(duì)輸出進(jìn)行重定向*/
if(ptr->outfd!=1)
{
close(1);
dup(ptr->outfd);
}
/*前臺(tái)進(jìn)程可以接受鍵盤輸入的中斷和退出信號(hào)*/
if(background==FALSE)
{
signal(SIGINT,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
}
/*關(guān)閉其它文件描述符,使得除了標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出2外設(shè)置的管道和I/O重定向*/
for(k=3;k<OPEN_MAX;++k)
close(k);
/*下面代碼執(zhí)行一條簡(jiǎn)單命令*/
execvp(ptr->av[0],ptr->av);
exit(1);
}
}
/*執(zhí)行輸入的命令的文件execute.c*/
execute(int j)
{
int m,fd,fds[2];
if(infile[0]!='\0')
/*如果命令指定了輸入文件則打開(kāi)輸入文件*/
cmdlin[0].infd=open(infile,O_RDONLY);
if(outfile[0]!= '\0')
/*如果命令指定了輸出文件則打開(kāi)相應(yīng)的輸出文件*/
if(append==FALSE)
cmdlin[j-1].outfd=open(outfile,O_WRONLY|O_CREAT|O_TRUNC,0666);
else
cmdlin[j-1].outfd=open(outfile,O_WRONLY|O_CREAT|O_APPEND,0666);
/*對(duì)前臺(tái)進(jìn)程和后臺(tái)進(jìn)程進(jìn)行不同的處理*/
if(background)
signal(SIGCHLD,SIG_IGN);
else
signal(SIGCHLD,SIG_DFL);
/*循環(huán)執(zhí)行每個(gè)簡(jiǎn)單命令*/
for(m=0;m<j;++m)
{
/*對(duì)管道進(jìn)行操作*/
if(m<j-1)
{
pipe(fds);
cmdlin[m+1].infd=fds[0];
cmdlin[m].outfd=fds[1];
}
/*執(zhí)行一條簡(jiǎn)單命令*/
run_com(&cmdlin[m]);
/*關(guān)閉該命令的輸入*/
if(fd=cmdlin[m].infd)
close(fd);
/*關(guān)閉該命令的輸出*/
if((fd=cmdlin[m].outfd)!=1)
close(fd);
}
/*如果不是后臺(tái)命令,等待直到最后一條簡(jiǎn)單命令執(zhí)行完畢*/
if(background==FALSE)
while(wait(NULL)!=lastpid);
}
/*分析簡(jiǎn)單命令get_sirmarg.c*/
get_simarg(int j)
{
int m,tag,inword;
for(m=0;m<MAXARG-1;++m)
{
while(*inputlnptr== ' '||*inputlnptr== '\t')
/*跳過(guò)空格符合Tab符*/
++inputlnptr;
/*在cmd數(shù)組中存放的j個(gè)量,如果j為0則為命令,否則為參數(shù)*/
cmdlin[j].av[m]=avptr;
cmdlin[j].av[m+1]=NULL;
for(tag=0;tag==0;)
{
switch(*inputlnptr)
{
case ' ':
case '\t':
inword=FALSE;
/*對(duì)于這兩種情況指定下一個(gè)參數(shù)*/
*avptr++= '\0';
tag=1;
break;
case '>':
case '\n':
case '<':
case '&':
case '|':
if(inword==FALSE)
/*對(duì)于以上幾種情況改命令結(jié)束*/
cmdlin[j].av[m]=NULL;
*avptr++= '\0';
return;
default:
/*否則說(shuō)明參數(shù)的名字還不全*/
inword=TRUE;
avptr=inputlnptr;
avptr++;
break;
}
}
}
}
/*字符串匹配check.c*/
check(char *ptr)
{
char *tptr;
while(*inputlnptr== ' ')
/*跳過(guò)空格符*/
inputlnptr++;
tptr=inputlnptr;
while(*ptr!= '\0'&&*ptr==*tptr)
/*循環(huán)比較兩個(gè)字符串是否相等*/
{
ptr++;
tptr++;
}
if(*ptr= '\0')
/*比較結(jié)果相等*/
{
inputlnptr=tptr;
/*修改inputlnptr指針*/
return(TRUE);
}
else
/*比較結(jié)果不相等*/
return(FALSE);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -