System Programming Lab 3. Shell Lab - 1

Layfort·2024년 1월 4일
0

System Programming

목록 보기
5/5

Shell Lab

  • linux에서 우리가 지금까지 사용해 왔던 Cmd와 같은 shell을 직접 구현해 보는 과제이다.
  • 관련 주제
    1. process(fork, exec): 기본적으로 shell은 사용자의 입력을 받아 프로그램을 실행시켜주는 프로그램이라고 생각하면 편하다. 따라서 사용자의 입력에 맞는 프로그램을 실행시킬 child process를 만들고, 해당 process를 적절하게 관리하는 것이 shell lab의 주된 목표이다.
    2. signal(signal handling): shell에서 실행되는 child들이 parent에게 다양한 신호를 보내기도 하고, 또한 반대로 Ctrl + CCtrl + Z와 같이 parent에서 child로 가는 신호도 있다. 이러한 신호들에 대해서 올바르게 처리하는 것
    3. IPC(pipe, redirection)
  • 관련 함수
    1. fork(): child process를 만들어야지
    2. exec(): exec계열 함수는 정말 엄청나게 많다... 그중에서 올바른 것을 찾는 것 또한 능력이 아닐까
    3. kill(): parent에서 child로 signal을 보내기
    4. signal(): child가 보낸 signal을 올바르게 handling하기
    5. dup2(): I/O redirection(>, <) - 사실은 >>이나 <<같은 redirection도 있는 것 같지만... 본 과제의 spec에 포함되지는 않는다.
    6. pipe(): pipe 기능 구현(|)

1. Trace 2.

  • 입력받은 프로그램을 ForeGround에서 실행하기!
  • 구현해야 하는 코드: eval()
void eval(char *cmdline)
{
  #define P_READ  0                      // pipe read end
  #define P_WRITE 1                      // pipe write end

  char *str = strdup(cmdline);
  VERBOSE("eval(%s)", stripnewline(str));
  free(str);

  char ***argv  = NULL;
  char *infile  = NULL;
  char *outfile = NULL;
  JobState mode;
  sigset_t mask;

  // parse command line
  int ncmd = parse_cmdline(cmdline, &mode, &argv, &infile, &outfile);
  VERBOSE("parse_cmdline(...) = %d", ncmd);
  if (ncmd == -1) return;              // parse error
  if (ncmd == 0)  return;              // no input
  assert(ncmd > 0);

  // dump parsed command line
  if (verbose) dump_cmdstruct(argv, infile, outfile, mode);

  // if the command is a single built-in command (no pipes or redirection), do not fork. Instead,
  // execute the command directly in this process. Note that this is not just to be more efficient -
  // it is necessary for the 'quit' command to work.
  if ((ncmd == 1) && (outfile == NULL)) {
    if (builtin_cmd(argv[0])) {
      free_cmdstruct(argv);
      return;
    }
  }

  // store pid for job struct
  // we will use this pid for search job
  pid_t *pid = malloc(sizeof(pid_t) * ncmd);

  if((pid[0] = fork()) < 0) {
    printf("fork error: %s\n", strerror(errno));
    exit(EXIT_FAILURE);
  }
  else if (pid[0] == 0) {
    setpgid(0, 0);

    if(execvp(argv[0][0], argv[0]) < 0) {
      printf("%s: Command not found\n", argv[0][0]);
      exit(EXIT_FAILURE);
    }
  }
  
  int jid = addjob(pid[0], pid, ncmd, mode, cmdline);

  if (mode == jsForeground) {
    waitfg(jid);
  }
  else {
    printjob(jid);
  }
}

2. Trace 3.

profile
물리와 컴퓨터

0개의 댓글