2013-04-14 14 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

你試過谷歌嗎?我發現了一些相關的內容[這裏](http://programmers.stackexchange.com/questions/162940/how-do-i-implement-the-bg-and-fg-commands-functionaliity-in-my-custom-unix -s)。 – RageD

+0

@RageD我不明白「我寫的命令bash解釋器的相似性。」意味着!!這句話令人困惑。 –

+0

相關:http://stackoverflow.com/q/5785988/951890 –

回答

0

對不起。我只是忘了發送SIGCONT進程和一切。添加並工作。 kill(bkgrnds[num], SIGCONT);

相關問題