c - 如何将进程移动到前台

标签 c bash unix pid background-foreground

我写了命令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

<- 这里继续猫 提前致谢。

最佳答案

抱歉。我只是忘记发送 SIGCONT 进程和所有内容。添加并工作。 kill(bkgrnds[num], SIGCONT);

关于c - 如何将进程移动到前台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16000014/

相关文章:

bash - if 条件与多个 grep 命令不起作用

bash - 使用 join/awk/sed 合并 CSV 文件

linux - fdisk - 创建一半磁盘大小的交换分区

python - Python 中是否有相当于 Unix 中 vfork 的工具?

c - 在 C 中使用 GTK+ 单击按钮后 GUI 变得无响应

c - 指针,计数器变得困惑

c - Gmp mpf_pow_ui 函数

c - C 中基于一个的索引技巧安全吗?

bash -/dev/stdin 与 herestring

linux - 使用 ls 进行管道传输时,grep 命令在 solaris 中不起作用