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

📄 tsh.c

📁 os project / shell 程序
💻 C
📖 第 1 页 / 共 2 页
字号:
*/void execute_cd(char **argv){	int index = strlen(argv[1]);	int i = 0;	char swap[128];	if(argv[1] == NULL){		chdir("/");		getcwd(prompt,128);	}else if(argv[1][0] == '/'){			chdir(argv[1]);				getcwd(prompt,128);				}else if(!strcmp(argv[1],"../")){				getcwd(prompt,128);				index = strlen(prompt) - 1;				while(prompt[index]!='/')				   index--;				strncpy(swap, prompt, index);							chdir(swap);				return;				}else{				getcwd(prompt,128);			        strcat(prompt,"/");      			        strcat(prompt,argv[1]);				chdir(prompt);			}	return;}/**makedir - build the dictory you wanted*/void makedir(char **argv){	int status;	status = mkdir(argv[1]);	if(status == 0)		perror("Directory created!\n");	else perror("Unable to create the directory\n");}/**removedir - remove the dictory you have choosed*/void removedir(char **argv){	int status;	status = rmdir(argv[1]);	if(status == 0)		perror("Directory removed!\n");	else		perror("Unable to remove the directory!\n");}/*  * do_bgfg - Execute the builtin bg and fg commands */void do_bgfg(char **argv, int output_fd) {         struct job_t *job=NULL;        if(argv[1]==NULL)         /*bg\fg command without pid\jid*/	{	    printf("%s command requires PID or %%jobid argument\n",argv[0]);	    return;	}	        if(argv[1][0]=='%')        /*%jid is a jid*/	{	   int jid;	   jid=atoi(argv[1]+1);	   if((job=getjobjid(jobs, jid))==NULL)  /*is the job found*/	   {	       printf("%s NO such job\n",argv[1]);	       return;	   }	}	else{	   if(!isdigit(*argv[1]))   /*is the pid a digit*/	   {	       printf("%s  argument must be a PID or %%jobid\n",argv[0]);	       return;	   }	   pid_t pid=(pid_t)atoi(argv[1]); 	   if((job=getjobpid(jobs, pid))==NULL)	   {	       printf("%s NO such process\n",argv[1]); 	       return;	   }	}	kill(-(job->pid),SIGCONT);   /*send a signal to the process and its child*/        if(!strcmp(argv[0],"bg"))	{            job->state=BG;         /*change state*/	    printf("[%d] (%d) %s",job->jid,job->pid,job->cmdline);           }        else	{            job->state=FG;        /*change state*/	    waitfg(job->pid,output_fd); /*wait the foreground process to terminate*/        }	return;}/*  * waitfg - Block until process pid is no longer the foreground process */void waitfg(pid_t pid, int output_fd){        struct job_t *job;        job=getjobpid(jobs,pid);        while((job!=NULL)&&job->state==FG)  /*if process pid foreground*/	{             sleep(1);         }        return;}/***************** * Signal handlers *****************//*  * sigchld_handler - The kernel sends a SIGCHLD to the shell whenever *     a child job terminates (becomes a zombie), or stops because it *     received a SIGSTOP or SIGTSTP signal. The handler reaps all *     available zombie children, but doesn't wait for any other *     currently running children to terminate.   */void sigchld_handler(int sig) {        struct job_t *job;	int status;	int jid;        pid_t pid;        while((pid=waitpid(-1,&status,WNOHANG|WUNTRACED))>0)	{	     job=getjobpid(jobs,pid);             if(WIFSTOPPED(status))    /*if the job stopped by signal*/	     {	          printf("Job [%d] (%d) stopped by signal %d\n",pid2jid(pid),pid,WSTOPSIG(status));	          job->state=ST;       /*change job state to stopped*/	     }	     else if(WIFEXITED(status))  /*if the job terminated normally*/	     {	          deletejob(jobs,pid);  /*delete the job from job list*/	     }	     else if(WIFSIGNALED(status)) /*if the job terminated by signal*/	     {	          if((jid=job->jid)>0)	                printf("Job [%d] (%d) terminated by signal %d\n",jid,pid,WTERMSIG(status));	          deletejob(jobs,pid); 	     }              }	        if(errno!=ECHILD&&errno!=EINTR)            unix_error("waitpid error");	return;}/*  * sigint_handler - The kernel sends a SIGINT to the shell whenver the *    user types ctrl-c at the keyboard.  Catch it and send it along *    to the foreground job.   */void sigint_handler(int sig) {        pid_t pid;        pid=fgpid(jobs);   /*get the foreground job*/	if(!pid)    /*if the foreground job exist*/	  return;        kill(-pid,SIGINT);     /*send signal SIGINT to the foreground process and its cild*/	return ;}/* * sigtstp_handler - The kernel sends a SIGTSTP to the shell whenever *     the user types ctrl-z at the keyboard. Catch it and suspend the *     foreground job by sending it a SIGTSTP.   */void sigtstp_handler(int sig) {	pid_t pid;        pid=fgpid(jobs);      /*get the foreground job*/	if(!pid)	  return;        kill(-pid,SIGTSTP);    /*send signal SIGTSTP to the foreground process and its cild*/	return;}/********************* * End signal handlers *********************//*********************************************** * Helper routines that manipulate the job list **********************************************//* clearjob - Clear the entries in a job struct */void clearjob(struct job_t *job) {	job->pid = 0;	job->jid = 0;	job->state = UNDEF;	job->cmdline[0] = '\0';}/* initjobs - Initialize the job list */void initjobs(struct job_t *jobs) {	int i;		for (i = 0; i < MAXJOBS; i++)		clearjob(&jobs[i]);}/* maxjid - Returns largest allocated job ID */int maxjid(struct job_t *jobs) {	int i, max=0;		for (i = 0; i < MAXJOBS; i++)		if (jobs[i].jid > max)			max = jobs[i].jid;	return max;}/* addjob - Add a job to the job list */int addjob(struct job_t *jobs, pid_t pid, int state, char *cmdline) {	int i;		if (pid < 1)		return 0;		for (i = 0; i < MAXJOBS; i++) {		if (jobs[i].pid == 0) {			jobs[i].pid = pid;			jobs[i].state = state;			jobs[i].jid = nextjid++;			if (nextjid > MAXJOBS)				nextjid = 1;			strcpy(jobs[i].cmdline, cmdline);			if(verbose){				printf("Added job [%d] %d %s\n", jobs[i].jid, jobs[i].pid, jobs[i].cmdline);			}			return 1;		}	}	printf("Tried to create too many jobs\n");	return 0;}/* deletejob - Delete a job whose PID=pid from the job list */int deletejob(struct job_t *jobs, pid_t pid) {	int i;		if (pid < 1)		return 0;		for (i = 0; i < MAXJOBS; i++) {		if (jobs[i].pid == pid) {			clearjob(&jobs[i]);			nextjid = maxjid(jobs)+1;			return 1;		}	}	return 0;}/* fgpid - Return PID of current foreground job, 0 if no such job */pid_t fgpid(struct job_t *jobs) {	int i;		for (i = 0; i < MAXJOBS; i++)		if (jobs[i].state == FG)			return jobs[i].pid;	return 0;}/* getjobpid  - Find a job (by PID) on the job list */struct job_t *getjobpid(struct job_t *jobs, pid_t pid) {	int i;		if (pid < 1)		return NULL;	for (i = 0; i < MAXJOBS; i++)		if (jobs[i].pid == pid)			return &jobs[i];	return NULL;}/* getjobjid  - Find a job (by JID) on the job list */struct job_t *getjobjid(struct job_t *jobs, int jid) {	int i;		if (jid < 1)		return NULL;	for (i = 0; i < MAXJOBS; i++)		if (jobs[i].jid == jid)			return &jobs[i];	return NULL;}/* pid2jid - Map process ID to job ID */int pid2jid(pid_t pid) {	int i;		if (pid < 1)		return 0;	for (i = 0; i < MAXJOBS; i++)		if (jobs[i].pid == pid) {			return jobs[i].jid;		}	return 0;}/* listjobs - Print the job list */void listjobs(struct job_t *jobs, int output_fd) {	int i;	char buf[MAXLINE];		for (i = 0; i < MAXJOBS; i++) {		memset(buf, '\0', MAXLINE);		if (jobs[i].pid != 0) {			sprintf(buf, "[%d] (%d) ", jobs[i].jid, jobs[i].pid);			if(write(output_fd, buf, strlen(buf)) < 0) {				fprintf(stderr, "Error writing to output file\n");				exit(1);			}			memset(buf, '\0', MAXLINE);			switch (jobs[i].state) {				case BG: 					sprintf(buf, "Running    ");					break;				case FG: 					sprintf(buf, "Foreground ");					break;				case ST: 					sprintf(buf, "Stopped    ");					break;				default:					sprintf(buf, "listjobs: Internal error: job[%d].state=%d ", 						i, jobs[i].state);			}			if(write(output_fd, buf, strlen(buf)) < 0) {				fprintf(stderr, "Error writing to output file\n");				exit(1);			}			memset(buf, '\0', MAXLINE);			sprintf(buf, "%s", jobs[i].cmdline);			if(write(output_fd, buf, strlen(buf)) < 0) {				fprintf(stderr, "Error writing to output file\n");				exit(1);			}		}	}	if(output_fd != STDOUT_FILENO)		close(output_fd);}/****************************** * end job list helper routines ******************************//*********************** * Other helper routines ***********************//* * usage - print a help message */void usage(void) {	printf("Usage: shell [-hvp]\n");	printf("   -h   print this message\n");	printf("   -v   print additional diagnostic information\n");	printf("   -p   do not emit a command prompt\n");	exit(1);}/* * unix_error - unix-style error routine */void unix_error(char *msg){	fprintf(stderr, "%s: %s\n", msg, strerror(errno));	exit(1);}/* * app_error - application-style error routine */void app_error(char *msg){	fprintf(stderr, "%s\n", msg);	exit(1);}/* * Signal - wrapper for the sigaction function */handler_t *Signal(int signum, handler_t *handler) {	struct sigaction action, old_action;		action.sa_handler = handler;  	sigemptyset(&action.sa_mask); /* block sigs of type being handled */	action.sa_flags = SA_RESTART; /* restart syscalls if possible */		if (sigaction(signum, &action, &old_action) < 0)		unix_error("Signal error");	return (old_action.sa_handler);}/* * sigquit_handler - The driver program can gracefully terminate the *    child shell by sending it a SIGQUIT signal. */void sigquit_handler(int sig) {	if (verbose)		printf("siquit_handler: terminating after receipt of SIGQUIT signal\n");	exit(1);}

⌨️ 快捷键说明

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