Skip to content

Instantly share code, notes, and snippets.

@scutdavy
Created December 5, 2013 04:35
Show Gist options
  • Save scutdavy/7800173 to your computer and use it in GitHub Desktop.
Save scutdavy/7800173 to your computer and use it in GitHub Desktop.
unix shell简单实现,支持参数,管道,重定向
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>
#define TRUE 1
int main(void) {
pid_t pid;
while(TRUE) {
printf("> ");
char buf[100];
if (!fgets(buf, 100, stdin)) return 0;
char *arg_list[10];
arg_list[0] = strtok(buf, " \n");
{
int i = 0;
while(arg_list[i] != NULL) {
i++;
arg_list[i] = strtok(NULL, " \n");
}
}
pid = fork();
if (pid == -1) return 1;
if (pid == 0){
{// io redirection support
int i = 0;
while(arg_list[i] != NULL){
char *current_token = arg_list[i];
if (strcmp(current_token, ">") == 0){
arg_list[i] = NULL; // single command support
char *file = arg_list[i+1];
if (file == NULL) break;
int fd = open(file, O_RDWR | O_CREAT, 0x755);
if (fd == -1){
printf("%d\n", fd);
printf("%s\n", strerror(errno));
break;
}
dup2(fd, STDOUT_FILENO);
break;
}
i++;
}
}
{// pipe
int i = 0;
while(arg_list[i] != NULL){
char *current_token = arg_list[i];
if (strcmp(current_token, "|") == 0){
arg_list[i] = NULL;
char ** arg1 = &arg_list[i+1];
int fds[2];
if (pipe(fds) == -1) break;
pid_t pid = fork();
if (pid == -1) break;
if (pid == 0){
close(fds[1]);
dup2(fds[0], STDIN_FILENO);
execvp(arg1[0], arg1);
}else{
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
}
break;
}
i++;
}
}
execvp(arg_list[0], arg_list);
}else{
int status;
waitpid(-1, &status, 0);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment