从进程中提取命令(使用PID)

时间:2012-03-02 11:37:44

标签: c exec fork signals

我在C中实现了简单的shell模拟器。它应该支持后台运行命令(例如sleep 5s&)。所以我使用fork() - >运行此命令exec()序列并使用SIGCHLD信号处理程序等待该命令的完成。我的问题是,如果有可能获得进程命令(名称),那就是在exec()调用中指定的。我举个例子:

//SIGCHLD signal handler (use for notification, when background process ends)
void sighandler(int sig) {
    int status;
    int pid = waitpid(-1, &status, WNOHANG);

    if (WIFEXITED(status)) {
        if (pid != -1 && pid != 0) {
            printf("\n[%d] Done: \n> ", (int) pid); //also need to provide user name (command) of exited process (ex. [PID] Done: sleep)
            fflush(stdout);
        }
    }
}

pid_t fork_pid = fork()

if (fork_pid == 0) { //child
    execl("sleep", "sleep", "5s");
} else { //parent
    ....
}

我需要的是以某种方式访问​​命令的名称,这是在exec()调用中指定的(参见execl(“sleep”,“sleep”,“5s”);)在信号处理程序中(参见signalhandler(int sig))输出像[PID]完成的东西:睡觉。

我不能使用上次运行命令的简单全局变量,因为在后台运行一些命令后,前景中会出现更多新命令并重写该全局变量。例如:

> sleep 1m & //background command - variable is "sleep"
[PID of sleep process] Running in background
> ls //foreground command - variable is "ls"
> cat output //foreground command - variable is "cat"
.
.
.
[PID of sleep process] Done: sleep
>

任何方式这样做?非常感谢!

1 个答案:

答案 0 :(得分:1)

您可以创建一个列表以将pids与命令相关联:

void sighandler(int sig) {
            ...
            char *cmd = task_list.get(pid);
            printf("\n[%d] %s, Done: \n> ", (int) pid, cmd);
            ...
}

...    

pid_t fork_pid = fork();
char command[1024] = "sleep";
if (fork_pid == 0) { //child
      execl(command, command, "5s");
} else { //parent
      task_list.insert(pid, command);
}