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