操作系统实践(六)

  本次实验课也是没有新内容,继续对重定向、管道进行综合训练,题目如下:
在这里插入图片描述
  但是,我没写出来!所以这篇先放一个好兄弟的代码,等过段时间不忙了再分析他的写自己的,嘿嘿!代码如下(因为不是一个人的代码,所以代码风格和前几版都不太相同,学优点就ok):

#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include<string.h>
#include<sys/stat.h> 
#include<fcntl.h>
char *command_begin;
int commnd_count = 0;
#define MAX_SIZE 1024
#define TRUE 1
#define MAX_ARGC 16
#define MAX_COMMANDS 64
#define MAX_S 64
typedef struct s_command {
    
    
	int argc;
	char *argv[MAX_ARGC];
	char *input;   //用于重定向输入 
	char *output;	 //用于重定向输出 
}s_command;

s_command commands[MAX_COMMANDS];
int parse_command(char *command);
int parse_commands(char *command);
char** _splite(const char *command, char ch);
void func_echo(char * opt);
void mysys(struct s_command *c);
void exec_pipe();


int main(int argc,char *argv[]) {
    
    
while(TRUE) {
    
    
	char ch[] =">";
	char *opt = (char *)malloc(sizeof(char)* MAX_SIZE);
	write(1,ch,strlen(ch));

	int size;
	size = read(0, opt, MAX_SIZE);

	if (size < 0) {
    
    
		printf("Read error\n");
		exit(0);
	}

	opt[size - 1] = '\0';
	command_begin = (char *)malloc(sizeof(char)*MAX_SIZE);
	strcpy(command_begin, opt);
	parse_commands(opt);
	if (commands[0].argv != NULL && !strcmp("exit",commands[0].argv[0]) ) {
    
    
		printf("exit\n");
		exit(0);
	}
	if (commnd_count == 1) {
    
    
		pid_t pi;
		pi = fork();
		if (pi == 0) {
    
    
			mysys(&commands[0]);
			exit(0);
		}
		wait(0);
	}
	else {
    
    
		pid_t pid;
		pid = fork();
		if (pid < 0) {
    
    
			printf("Error,create process error\n");
			exit(0);
		}
		else if (pid == 0) {
    
    
			exec_pipe();
			exit(0);
		}
		wait(NULL);
	}


	commnd_count = 0;
	memset(&commands,0,sizeof(commands));
}
	return 0;
}

int parse_command(char *command) {
    
    
	char *inner_ptr = NULL;
	int ar = 0;
	char *word;
	word = strtok_r(command, " ", &inner_ptr);
	while (word != NULL) {
    
    
		commands[commnd_count].argv[ar] = (char *)malloc(sizeof(char)*MAX_S);
		strcpy(commands[commnd_count].argv[ar], word);
		ar++;
		word = strtok_r(NULL, " ", &inner_ptr);
	}
	commands[commnd_count].argv[ar] = NULL;
	return ar;
}

int parse_commands(char *command) {
    
    
	char *outer_ptr = NULL;
	char *word;
	word = strtok_r(command, "|", &outer_ptr);
	while (word != NULL) {
    
    
		char buffer[100];
		strcpy(buffer, word);
		commands[commnd_count].argc = parse_command(buffer);
		commnd_count++;
		word = strtok_r(NULL, "|", &outer_ptr);
	}
	return commnd_count;

}

char** _splite(const char *command, char ch) {
    
    
	char * temp = (char *)malloc(sizeof(char *) * (strlen(command) + 1));
	char **rec;
	int count = 0;
	for (int i = 0; i < strlen(command); i++) {
    
    
		if (command[i] == ch) {
    
    
			temp[i] = '\0';
			count++;
			continue;
		}
		temp[i] = command[i];
	}
	temp[strlen(command) - 1] = '\0';
	rec = (char **)malloc(sizeof(char*)*(count + 1));
	count = 0;
	int st = 0;
	for (int i = 0; i < strlen(command); i++) {
    
    
		if (temp[i] == '\0') {
    
    

			rec[count] = (char *)malloc(sizeof(char) * sizeof(&temp[st]));
			strcpy(rec[count], &temp[st]);
			st = i + 1;
			count++;
		}
	}
	rec[count] = NULL;
	return rec;
}
void func_echo(char * opt) {
    
    
	char * temp = (char *)malloc(sizeof(char *) * (strlen(opt) + 1));
	for (int i = 0; i < strlen(opt); i++) {
    
    
		temp[i] = opt[i];
	}
	int sign = 0; // judge > front or behind
	char *echo_s;
	char *file_name;
	for (int i = 4; i < strlen(opt); i++) {
    
    
		if (opt[i] == '>') {
    
    
			temp[i] = '\0';
			echo_s = (char *)malloc(sizeof(char)*(i));
			strcpy(echo_s, &temp[5]);
			sign = 1;
		}
		else if (sign == 1) {
    
    
			if (opt[i] == ' ')	continue;
			file_name = (char *)malloc(sizeof(char)*(strlen(opt)));
			strcpy(file_name, &temp[i]);
			break;
		}
	}
	char ch[] = "\n";
	if (sign == 0) {
    
    
		echo_s = (char *)malloc(sizeof(char)*strlen(opt));
		strcpy(echo_s, &opt[5]);
		write(1, echo_s, strlen(echo_s));
		write(1, ch, strlen(ch));
	}
	else {
    
    

		int fd = creat(file_name, 0777);
		if (fd == -1) {
    
    
			puts("Create error");
			exit(0);
		}
		dup2(fd, 1);
		close(fd);
		write(1, echo_s, strlen(echo_s));
		write(1, ch, strlen(ch));

	}
}

void mysys(struct s_command *c) {
    
    
	char buff[MAX_SIZE];
	if (c->argv != NULL && !strcmp("pwd", c->argv[0])) {
    
    
		char *cwd = getcwd(buff, sizeof(buff));
		if (cwd == NULL) {
    
    
			printf("error\n");
			exit(-1);
		}
		else {
    
    
			printf("current dir: %s\n", cwd);
		}
	}
	else if (c->argv != NULL && !strcmp("cd", c->argv[0])) {
    
    
		if (c->argv[1] == NULL) {
    
    
			printf("parenter error\n");
			exit(0);
		}
		else {
    
    
			chdir(c->argv[1]);
		}
	}
	else if (c->argv != NULL && !strcmp("echo", c->argv[0])) {
    
    
		int p = fork();
		if (p == 0) {
    
    
			func_echo(command_begin);
			exit(0);
		}
		wait(NULL);
	}
	else {
    
    
		pid_t pid;
		pid = fork();
		if (pid < 0) {
    
    
			printf("Error,create process error\n");
			exit(0);
		}
		else if (pid == 0) {
    
    
			execvp(c->argv[0], c->argv);
			exit(0);
		}
		wait(NULL);
	}

}

void exec_pipe() {
    
    
	int fd[2];
	pipe(fd);
	pid_t pid;
	pid = fork();
	if (pid < 0) {
    
    
		printf("Error,create process error\n");
		exit(0);
	}
	else if (pid == 0) {
    
    
		dup2(fd[0], 0);
		close(fd[1]);
		close(fd[0]);
		mysys(&commands[1]);
		exit(0);
	}
	dup2(fd[1], 1);
	close(fd[1]);
	close(fd[0]);
	mysys(&commands[0]);
}

Guess you like

Origin blog.csdn.net/gls_nuaa/article/details/117392085