2013-04-14 4 views
-2

bash 인터프리터의 유사성을 씁니다.전경에서 프로세스를 이동하는 방법

#include <sys/types.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <signal.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <wait.h> 
#include "shell.h" 
#include <string.h> 

char *infile; 
char *outfile; 
char *appfile; 
struct command cmds[MAXCMDS]; 
char bkgrnd; 
int k = 0; 

static void my_wait(pid_t pid, pid_t bkgrnds[]); 

int main(int argc,char *argv[]) 
{ 
    int i; 
    char line[1024];  /* allow large command lines */ 
    int ncmds; 
    char prompt[50];  /* shell prompt */ 
    pid_t bkgrnds[1024];  /* for fg */ 

    /* PLACE SIGNAL CODE HERE */ 
    signal(SIGINT, SIG_IGN); 
    signal(SIGTSTP, SIG_IGN); 

    sprintf(prompt,"[%s] ",argv[0]); 

    while (promptline(prompt, line, sizeof(line)) > 0) 
    { /* l eof */ 

     if (0 >= (ncmds = parseline(line))) 
     { 
      continue; /* read next line */ 
     } 
#ifdef DEBUG 
     { 
      int i, j; 
      for (i = 0; i < ncmds; i++) 
      { 
       for (j = 0; NULL != cmds[i].cmdargs[j]; j++) 
       { 
        fprintf(stderr, "cmd[%d].cmdargs[%d] = %s\n", i, j, cmds[i].cmdargs[j]); 
       } 
       fprintf(stderr, "cmds[%d].cmdflag = %o\n", i, [i].cmdflag); 
      } 
     } 
#endif 
     { 
      int previous_pipe_output = -1; 
      int pipeline_start = 0; 
      pid_t pids[MAXCMDS]; 
      fprintf(stderr, "%d %s\n", ncmds, cmds[0].cmdargs[0]); 
      if (1 == ncmds && 0 == strcmp(cmds[0].cmdargs[0], "fg")) 
      { 
       if (0 == k) 
       { 
        fprintf(stderr, "k == 0\n"); 
        continue; 
       } 
       int num = -1; 
       signal(SIGTTOU, SIG_IGN); 
       if (0 == cmds[0].cmdargs[1]) 
       { 
        num = k - 1; 
       } 
       else 
       { 
        num = atoi(cmds[0].cmdargs[1]); 
       } 
       fprintf(stderr, "%d\n", bkgrnds[num]); 

       if(-1 == tcsetpgrp(STDIN_FILENO, bkgrnds[num])) 
       { 
        perror("Couldn't set terminal foreground process group"); 
        return EXIT_FAILURE; 
       } 
       signal(SIGTTOU, SIG_DFL); 
       my_wait(bkgrnds[num], bkgrnds); 
       signal(SIGTTOU, SIG_IGN); 
       if (-1 == tcsetpgrp(STDIN_FILENO, getpgrp())) 
       { 
        perror("Couldn't set terminal foreground process group"); 
        return EXIT_FAILURE; 
       } 
       signal(SIGTTOU, SIG_DFL); 
       continue; 
      } 
      for (i = 0; i < ncmds; i++) 
      { 
       int pipefd[2] = {-1, -1}; 
       if(cmds[i].cmdflag & OUTPIP) 
       { 
        if(-1 == pipe(pipefd)) 
        { 
         perror("Couldn't create pipe"); 
         return EXIT_FAILURE; 
        } 
       } 
       { 
        /* FORK AND EXECUTE */ 
        pids[i] = fork(); 
        if (0 == pids[i]) 
        { 
         signal(SIGINT, SIG_DFL); 
         signal(SIGTSTP, SIG_DFL); 
         if(-1 == setpgid(0, (cmds[i].cmdflag & INPIP)? pids[pipeline_start]:0)) 
         { 
          perror("Couldn't set process group ID"); 
          return EXIT_FAILURE; 
         } 
         if (!bkgrnd && !(cmds[i].cmdflag & INPIP)) 
         { 
          signal(SIGTTOU, SIG_IGN); 
          if(-1 == tcsetpgrp(STDIN_FILENO, getpgrp())) 
          { 
           perror("Couldn't set terminal foreground process group"); 
           return EXIT_FAILURE; 
          } 
          signal(SIGTTOU, SIG_DFL); 
         } 

         //.... 
         execvp(cmds[i].cmdargs[0], cmds[i].cmdargs); 
         perror("Couldn't execute command"); 
         return EXIT_FAILURE; 
        } 
        else if (-1 != pids[i]) 
        { 
         if (!bkgrnd) 
         { 
          if (!(cmds[i].cmdflag & OUTPIP)) 
          { 
           { 
            int j = 0; 
            for (j = pipeline_start; j <= i; j++) 
            { 
             my_wait(pids[j], bkgrnds); 
            } 
           } 
           signal(SIGTTOU, SIG_IGN); 
           if (-1 == tcsetpgrp(STDIN_FILENO, getpgrp())) 
           { 
            perror("Couldn't set terminal foreground process group"); 
            return EXIT_FAILURE; 
           } 
           signal(SIGTTOU, SIG_DFL); 
          } 
         } 
         else 
         { 
          printf("Background process ID: %ld\n", (long)pids[i]); 
         } 
        } 
        else 
        { 
         perror("Couldn't create process"); 
        } 
       } 
      } 
     } 
    } /* close while */ 
    return EXIT_SUCCESS; 
} 

static void my_wait(pid_t pid, pid_t bkgrnds[]) 
{ 
    int status = 0; 
    if (-1 != waitpid(pid, &status, WUNTRACED)) 
    { 
     if (WIFSTOPPED(status) && (SIGTSTP == WSTOPSIG(status))) 
     { 
      bkgrnds[k++] = pid; 
      //printf("%d %d\n", pid, k); 
      kill(pid, SIGCONT); 
      bkgrnd = 1; 
      printf("Background process ID: %ld\n", (long)pid); 
     } 
    } 
    else 
    { 
     perror("Couldn't wait for child process termination"); 
    } 

} 

이제 fg 명령을 구현하고 싶습니다.

if (1 == ncmds && 0 == strcmp(cmds[0].cmdargs[0], "fg")) 
      { 
       if (0 == k) 
       { 
        fprintf(stderr, "k == 0\n"); 
        continue; 
       } 
       int num = -1; 
       signal(SIGTTOU, SIG_IGN); 
       if (0 == cmds[0].cmdargs[1]) 
       { 
        num = k - 1; 
       } 
       else 
       { 
        num = atoi(cmds[0].cmdargs[1]); 
       } 
       fprintf(stderr, "%d\n", bkgrnds[num]); 

       if(-1 == tcsetpgrp(STDIN_FILENO, bkgrnds[num])) 
       { 
        perror("Couldn't set terminal foreground process group"); 
        return EXIT_FAILURE; 
       } 
       signal(SIGTTOU, SIG_DFL); 
       my_wait(bkgrnds[num], bkgrnds); 
       signal(SIGTTOU, SIG_IGN); 
       if (-1 == tcsetpgrp(STDIN_FILENO, getpgrp())) 
       { 
        perror("Couldn't set terminal foreground process group"); 
        return EXIT_FAILURE; 
       } 
       signal(SIGTTOU, SIG_DFL); 
       continue; 
      } 

질문 : PID 내가 전경으로 가져 오는 방법을 알고 있습니까? 여기 고양이에게 사전에 감사를 지속되어야한다 - 나는

고양이

CTRL + Z

FG

<을 가져 오는 경우입니다 .

+0

Google을 사용해 보셨나요? 나는 뭔가 [여기]를 발견했다. (http://programmers.stackexchange.com/questions/162940/how-do-i-implement-the-bg-and-fg-commands-functionaliity-in-my-custom-unix -에스). – RageD

+0

@RageD "나는 bash 인터프리터 명령의 유사성을 쓴다." 의미! 문장은 혼란 스럽다. –

+0

관련 항목 : http://stackoverflow.com/q/5785988/951890 –

답변

0

죄송합니다. 방금 SIGCONT 프로세스와 모든 것을 보내는 것을 잊었습니다. 추가 및 작업 중. kill(bkgrnds[num], SIGCONT);