Skip to content

Commit 04a1b6d

Browse files
authored
0.0 version (#33)
0.0 version
1 parent 1ae10d4 commit 04a1b6d

13 files changed

+706
-0
lines changed

Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CC=gcc
2+
CFLAGS=-g -Wall
3+
OBJS=main.o command_line.o get_token.o is_redirection.o is_pipe.o change_directory.o process_pipe.o background.o process_redir.o fork_and_call_process_redir.o
4+
TARGET=minishell
5+
6+
$(TARGET): $(OBJS)
7+
$(CC) -o $@ $(OBJS)
8+
9+
main.o: header.h main.c
10+
command_line.o: header.h command_line.c
11+
get_token.o: header.h get_token.c
12+
is_redirection.o: header.h is_redirection.c
13+
is_pipe.o: header.h is_pipe.c
14+
change_directory.o: header.h change_directory.c
15+
process_pipe.o: header.h process_pipe.c
16+
background.o: header.h background.c
17+
process_redir.o: header.h process_redir.c
18+
fork_and_call_process_redir.o: header.h fork_and_call_process_redir.c

background.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#include "header.h"
2+
3+
int cnt;
4+
int current_cnt;
5+
int largest_num;
6+
char command[512];
7+
char current_command[512];
8+
9+
void handle_signal (int sig)
10+
{
11+
cnt = cnt - 1;
12+
}
13+
14+
void background(char **arg, int index)
15+
{
16+
17+
if(cnt==0)
18+
{
19+
current_cnt = ++cnt;
20+
largest_num = current_cnt;
21+
}
22+
else
23+
{
24+
current_cnt = ++largest_num;
25+
++cnt;
26+
}
27+
28+
memset(command,0,sizeof(command));
29+
for(int i = 0 ; i < index ; i++)
30+
{
31+
strcat(command,arg[i]);
32+
strcat(command," ");
33+
}
34+
strcpy(current_command,command);
35+
36+
37+
int ppid = getpid();
38+
int pid1 = fork();
39+
int pstatus = 0;
40+
int ppstatus = 0;
41+
42+
signal(SIGUSR1,handle_signal);
43+
44+
if(pid1==0)
45+
{
46+
int pid2 = fork();
47+
if(pid2==0)
48+
{
49+
execvp(*arg,arg);
50+
}
51+
else
52+
{
53+
printf("\n[%d] %d\n",current_cnt,pid2);
54+
waitpid(pid2,&pstatus,WUNTRACED);
55+
kill(ppid,SIGUSR1);
56+
printf("[%d] Done \t\t\t %s\n",current_cnt,current_command);
57+
kill(getpid(),SIGKILL);
58+
}
59+
}
60+
else
61+
{
62+
waitpid(pid1,&ppstatus,WNOHANG);
63+
}
64+
65+
}

change_directory.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include "header.h"
2+
3+
void change_directory(char** arg, int index)
4+
{
5+
struct passwd *password;
6+
char *home;
7+
char directory_path[SIZE];
8+
int flag = 0;
9+
int home_len = 0;
10+
11+
password = getpwuid(getuid());
12+
home = password -> pw_dir;
13+
home_len = strlen(home);
14+
15+
if(index >= 3)
16+
{
17+
printf("cd: too many arguments\n");
18+
}
19+
else if(index == 2)
20+
{
21+
if(!strncmp("~", arg[1], 2))
22+
flag = 1;
23+
if(!strncmp("-", arg[1], 2))
24+
flag = 2;
25+
if(!strncmp("~-", arg[1], 3))
26+
flag = 3;
27+
if(!strncmp("~/", arg[1], 2))
28+
flag = 4;
29+
30+
switch(flag)
31+
{
32+
case 1 :
33+
chdir(home);
34+
break;
35+
case 2 :
36+
printf("%s", previous_directory);
37+
if(strcmp("\0", previous_directory))
38+
printf("\n");
39+
case 3 :
40+
if(!strcmp("\0", previous_directory))
41+
{
42+
printf("cd: OLDPWD not set\n");
43+
break;
44+
}
45+
else
46+
{
47+
chdir(previous_directory);
48+
break;
49+
}
50+
case 4 :
51+
strcpy(directory_path, home);
52+
strcat(directory_path, arg[1] + 1);
53+
if(chdir(directory_path))
54+
printf("cd: %s: No such file or directory\n", directory_path);
55+
break;
56+
default :
57+
if(chdir(arg[1]))
58+
printf("cd: %s: No such file or directory\n", arg[1]);
59+
}
60+
}
61+
else
62+
{
63+
chdir(home);
64+
}
65+
66+
if(!strncmp(current_directory, "~", 1))
67+
{
68+
strcpy(previous_directory, home);
69+
strcat(previous_directory, current_directory + 1);
70+
}
71+
else
72+
strcpy(previous_directory, current_directory);
73+
74+
getcwd(current_directory, sizeof(current_directory));
75+
if(!strncmp(current_directory, home, home_len))
76+
{
77+
strcpy(directory_path, current_directory);
78+
strcpy(current_directory, "~");
79+
strcat(current_directory, directory_path + (home_len));
80+
}
81+
82+
return;
83+
}
84+
85+
/*
86+
~ : HOME (1)
87+
- : OLDPWD로 이동 (2)
88+
키자마자 바로하면 cd: OLDPWD not set
89+
~- : echo 없이 OLDPWD 이동 (3)
90+
~/[...] : 디렉토리 이동 (4)
91+
default : 디렉토리 그대로 chdir (0)
92+
93+
마지막에 current_directory와 previous_directory 세팅해 주기
94+
$HOME 이면 current_directory "~" 변환
95+
*/
96+

command_line.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include "header.h"
2+
3+
bool command_line()
4+
{
5+
char *arg[1024];
6+
bool flag_pipe = false;
7+
bool flag_redirection = false;
8+
bool flag_background = false;
9+
int type = 0;
10+
int index = 0;
11+
int how = 0;
12+
13+
fgets(input, 1024, stdin);
14+
tok = tokens;
15+
ptr = input;
16+
type = get_token(&arg[index++]);
17+
while (type != EOL)
18+
{
19+
type = get_token(&arg[index]);
20+
if(type == AMPERSAND)
21+
flag_background = true;
22+
if(type == ARG)
23+
index++;
24+
}
25+
arg[index] = NULL;
26+
if (!strcmp(arg[0], "quit") || !strcmp(arg[0], "exit"))
27+
return false;
28+
else
29+
{
30+
if (!strcmp(arg[0], "cd"))
31+
{
32+
change_directory(arg, index);
33+
return true;
34+
}
35+
flag_pipe = is_pipe(arg, index);
36+
flag_redirection = is_redirection(arg, index);
37+
38+
if (flag_pipe)
39+
process_pipe(arg, index, how);
40+
else if (flag_redirection)
41+
fork_and_call_process_redir(arg, index);
42+
else if (flag_background)
43+
background(arg, index);
44+
else
45+
{
46+
int pid = fork();
47+
int status = 0;
48+
49+
if(pid==0)
50+
{
51+
execvp(*arg, arg);
52+
exit(1);
53+
}
54+
else
55+
waitpid(-1,&status,0);
56+
57+
}
58+
return true;
59+
}
60+
}
61+

fork_and_call_process_redir.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "header.h"
2+
3+
void fork_and_call_process_redir(char **arg, int narg)
4+
{
5+
int pid;
6+
7+
if((pid = fork()) < 0)
8+
{
9+
perror("fork() error");
10+
exit(-1);
11+
}
12+
else if(pid == 0) // 자식 프로세스
13+
process_redir(arg, narg);
14+
15+
// 부모 프로세스 대기
16+
waitpid(pid, NULL, 0);
17+
18+
return;
19+
}

get_token.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include "header.h"
2+
3+
int get_token(char **arg)
4+
{
5+
// token 타입 저장
6+
int type = ARG;
7+
// token 시작 주소 arg로 넘겨주기
8+
*arg = tok;
9+
10+
// whitespace 뛰어넘기
11+
while((*ptr == ' ') || (*ptr == '\t'))
12+
ptr++;
13+
14+
switch(*tok++ = *ptr++)
15+
{
16+
case '&':
17+
type = AMPERSAND;
18+
break;
19+
case '\n':
20+
type = EOL;
21+
break;
22+
default:
23+
while((*ptr != ' ') && (*ptr != '\t') && (*ptr != '&') && (*ptr != '\n'))
24+
*tok++ = *ptr++;
25+
break;
26+
}
27+
*tok++ = '\0';
28+
29+
return type;
30+
}

header.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef __HEADER_H__
2+
#define __HEADER_H__
3+
4+
// 다른 헤더파일 include
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
#include <unistd.h>
8+
#include <string.h>
9+
#include <stdbool.h>
10+
#include <errno.h>
11+
#include <fcntl.h>
12+
#include <pwd.h>
13+
#include <signal.h>
14+
15+
// 상수 및 매크로 정의부
16+
#define AMPERSAND 0
17+
#define EOL 1
18+
#define ARG 2
19+
#define SIZE 1024
20+
21+
// 사용자 정의 type정의부
22+
23+
// 전역 변수 선언
24+
char current_directory[SIZE];
25+
char previous_directory[SIZE];
26+
char input[SIZE];
27+
char tokens[SIZE];
28+
char *ptr;
29+
char *tok;
30+
31+
// 함수 선언부
32+
int get_token(char **arg);
33+
void change_directory(char **arg, int index);
34+
bool is_pipe(char **arg, int size);
35+
bool is_redirection(char **arg, int size);
36+
bool command_line(void);
37+
void process_pipe(char **arg, int narg, int how);
38+
void background(char **arg, int index);
39+
void process_redir(char **arg, int narg);
40+
void fork_and_call_process_redir(char **arg, int narg);
41+
42+
#endif

is_pipe.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "header.h"
2+
3+
bool is_pipe(char **arg, int size)
4+
{
5+
bool result = false;
6+
7+
for(int i = 0; i < size; i++)
8+
if(!strcmp(arg[i], "|"))
9+
{
10+
result = true;
11+
break;
12+
}
13+
14+
return result;
15+
}
16+

is_redirection.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "header.h"
2+
3+
bool is_redirection(char **arg, int size)
4+
{
5+
bool result = false;
6+
7+
for(int i = 0; i < size; i++)
8+
if(!strcmp(arg[i], "<") || !strcmp(arg[i], ">") || !strncmp(arg[i], ">>", 3))
9+
{
10+
result = true;
11+
break;
12+
}
13+
14+
return result;
15+
}
16+

0 commit comments

Comments
 (0)