쉘 프로그램을 구현을 해보려고 한다.
쉘 이름은 SM_shell.
부족한 것도 많고 코드도 지저분할 수도 있지만 그래도 해봐야 늘지 않을까 싶다.
초기 형태만 잡아둔 상태고 명령어는 help, exit 두 개뿐이다.
// my_header.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#define STR_MAX 4096
#define PATH_MAX 4096
#define NOT_CMD 0b0000000
#define CMD_EXIT 0b0000001
#define CMD_HELP 0b0000010
char execPath[PATH_MAX];
char homePath[PATH_MAX];
char execName[PATH_MAX];
char *commandList[2] = {
"exit",
"help"
};
void help();
아래가 메인 코드이다.
// SM_shell.c
#include "my_header.h"
void helpExec() {
pid_t pid;
if ((pid = fork()) < 0) {
fprintf(stderr, "fork error\n");
exit(1);
}
else if (pid == 0) {
execl(execName, "help", (char *)0);
exit(0);
}
else {
pid = wait(NULL);
}
}
void init() {
getcwd(execPath, PATH_MAX);
sprintf(homePath, "%s", getenv("HOME"));
}
void prompt() {
char input[STR_MAX];
int command;
while (1) {
printf("SM_shell > ");
fgets(input, STR_MAX, stdin);
input[strlen(input) - 1] = '\0';
if (!strcmp(input, commandList[0])) { // exit
fprintf(stdout, "* SM_shell exit... *\n");
exit(0);
} else if (!strcmp(input, commandList[1])) { // help
command = CMD_HELP;
}
else {
command = NOT_CMD;
}
if (command & CMD_HELP || command == NOT_CMD) {
helpExec();
}
}
}
int main(int argc, char **argv) {
init();
strcpy(execName, argv[0]);
if (!strcmp(argv[0], "help")) {
help();
}
else {
prompt();
}
exit(0);
}
현재 Makefile은 이렇게 구성해 뒀다.
CC = gcc
TARGET = SM_shell
HEADER = my_header
OBJECTS = my_help.o
$(TARGET) : $(TARGET).o $(OBJECTS)
$(CC) -o $(TARGET) $(TARGET).o $(OBJECTS)
$(TARGET).o : $(HEADER).h $(TARGET).c
$(CC) -c -o $@ $(TARGET).c
my_help.o : my_help.c
$(CC) -c -o $@ $^
clean :
rm -rf $(TARGET)
rm -rf $(OBJECTS)
위 코드는 아래 이미지를 클릭해 깃허브에서도 확인할 수 있다.
'Linux > 쉘, 쉘 명령어 구현하기' 카테고리의 다른 글
[쉘 구현하기] execv() 사용을 위한 문자열 배열 만들기 (0) | 2023.08.11 |
---|---|
[쉘 구현하기] ls 명령어 터미널 크기에 최적화 (0) | 2023.08.09 |
[쉘 구현하기] ls 명령어 구현 (0) | 2023.08.09 |
[쉘 구현하기] pwd 명령어 구현 (0) | 2023.08.08 |
[쉘 구현하기] help 명령어 구현 (0) | 2023.08.08 |