728x90
시스템 프로그래밍 수강하면서 진짜 어려웠던 과제
몇 주를 머리를 싸맸는지 모르겠다.,...............,,,,,,,,,,,, 인터넷에 검색해도 안 나와서 진짜진짜 하다가 너무 화가나서.,.!!!!!!!!!!!!!!!!! 여기다 적는다.......... 이거 말고도 다른 코드들은 나의 깃허브로 커몬..,,,,,,,,, 여러분 고생ㅇ들이 많으세요 무엇보다 나도......고생했다........,,,,,,,,,,,,,,,,,,,,,,,
https://github.com/1000hyrm/SystemProgramming
리눅스 시스템프로그래밍 마이쉘 프로그램 Linux System programming myShell program
환경 : Ubuntu / Linux 환경 언어 : C언어
- 기존의 shell과 유사하게 무한 루프를 돌면서, 사용자의 명령을 입력받아, 입력 받은 명령을 child process가 수행하도록 한다.
- parent process는 child process가 종료할 때까지 기다린다.
- 이 프로그램이 수행되는 환경에 관한 내용(경로)은 .myshell 파일에 저장되어 있는 것으로 가정한다.
- 사용자가 myshell 상에서 "date"라고 입력하면, myShell 프로그램에서는 현재 디렉토리에 있는 .myshell파일에서 PATH를 읽어서 각 경로에 "date"라는 명령이 있는지 확인
- 명령이 있는 경우에 해당 프로그램을 실행
<결과 화면>
<코드 및 설명>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
int fd, i, status, pid;
char *pathPtr[20], allPath[1024], exStr[128], ch, line1[256];
if ((fd = open (".myshell", O_RDONLY)) <= 0) {
perror ("open error.");
exit (-1);
} //경로가 저장된 파일 오픈
memset (allPath, 0, 1024); //allPath를 1024크기만큼 0으로 채우기
while (1) { // discard "PATH="
read(fd, &ch, 1);
if (ch=='=')
break;
} //파일에 PATH=라고 시작하며 경로가 저장되어있으니 그걸 제거
read (fd, allPath, 1024); //경로를 1024만큼 읽어서 allPath에 저장
pathPtr[0] = strtok(allPath, ":\n");
i = 0;
while (pathPtr[i]!=NULL) {
printf("pathPtr[%d]=[%s]\n", i, pathPtr[i]);
i++;
pathPtr[i] = strtok(NULL, ":\n");
} //저장된 연속된 경로를 strtok를 이용해 하나씩 빼기(:를 기준으로 이어져있음)
//쉘 시작
while(1){
printf("%% ");
fgets(line1, 255, stdin); //명령어 입력
//경로가 저장될 때 \n도 같이 저장되어있으니 이걸 빼주는 작업
printf("str = %s\n", line1); //\n exist
line1[strlen(line1)-1]='\0';
strtok(line1, " ");
printf("new str = %s\n", line1);
strcpy (exStr, pathPtr[0]); //처음 나오는 경로를 exStr에 저장
strcat (exStr, "/"); //리눅스에서 '경로/명령어'로 입력해야하니 /를 삽입
printf ("-->[%s]\n", exStr);
strcat(exStr, line1); //'경로/명령어'로 나오게끔 명령어를 경로 다음에 삽입
//access는 파일 존재,권한 확인 함수
if(access(exStr, F_OK) == 0){ //'경로/명령어'가 존재하거나 접근 가능하면
printf("%s\n", exStr);
printf("Existed in pathPtr[0]\n");
if(fork() == 0){ //child process를 생성해서
execl(exStr, "exe", (char *)0); //명령을 실행하도록함
perror("fork error\n");
exit(-1);
}
pid = wait(&status);
printf("Parent: child exit. pid = [%d], status = [%x]\n", pid, status); //process id 반환
}
else{ //첫번째 경로에 없다면 두번째 경로에서 명령어 찾기
strcpy(exStr, pathPtr[1]);
strcat(exStr, "/");
printf ("try-->[%s]\n", exStr);
strcat(exStr, line1);
if(access(exStr, F_OK) == 0){ //'경로2/명령어'가 존재한다면
printf("%s\n", exStr);
printf("Existed in pathPtr[1]\n");
if(fork() == 0){ //child process를 생성해
execl(exStr, "exe", (char *)0); //명령어 실행
perror("fork error\n");
exit(-1);
}
pid = wait(&status);
printf("Parent: child exit. pid = [%d], status = [%x]\n", pid, status);
}
else{ //'경로2/명령어'가 존재하지 않는다면 경로3에서 찾기
strcpy(exStr, pathPtr[2]);
strcat(exStr, "/");
printf ("try2-->[%s]\n", exStr);
strcat(exStr, line1);
if(access(exStr, F_OK) == 0){ //'경로3/명령어'가 존재한다면
printf("%s\n", exStr);
printf("Finally, Existed in pathPtr[2]\n"); //드디어 찾았다!
if(fork() == 0){ //child process를 생성해 명령어 실행
execl(exStr, "exe", (char *)0);
perror("fork error\n");
exit(-1);
}
pid = wait(&status);
printf("Parent: child exit. pid = [%d], status = [%x]\n", pid, status);
}
else{ //모든 경로에서도 명령을 찾지 못한다면
printf("command not found\n");
}
}
}
}
}
.myshell 파일은 이렇게 생겼다
PATH=/usr/bin:/usr/local/bin:/bin
PATH=도 떼어주어야하고 :도 떼어주어야한다. 그 과정에서 strtok와 strcat을 사용..
이게 제일 어려웠다..,.,,, C언어를 써서 더더더더더 어려웠음 C언어 한참 전에 배웠는데.,, 포인터도 가물가물 파일 실행도 가물가물..,문자열이 제일 어렵다.,가물가물가물치...
시스템 프로그래밍.,,쉽지 않았다 덕분에 리눅스랑 좀 어색해짐
암튼 도움이 되시길 바라ㅇ요..
728x90
'LINUX > 시스템 프로그래밍' 카테고리의 다른 글
[시스템프로그래밍] thread 문제 (0) | 2022.06.29 |
---|